<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><div id="myscoll"></div><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>Node全栈 | 晚夜微雨问海棠のBlog</title><meta name="keywords" content="Node"><meta name="author" content="晚夜微雨问海棠"><meta name="copyright" content="晚夜微雨问海棠"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="Node.jsNode.js的简介和安装Node.js的简介 Node.js的发明人：Rayn Dahl 我们要树立一个观念，Node.js 不是一门新的语言，还是基于JavaScript进行编程的。 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境 Node 是一个让 JavaScript 运行在服务端的开发平台，它让 JavaScript 成为与PHP、P">
<meta property="og:type" content="article">
<meta property="og:title" content="Node全栈">
<meta property="og:url" content="http://example.com/posts/3a5743c3.html">
<meta property="og:site_name" content="晚夜微雨问海棠のBlog">
<meta property="og:description" content="Node.jsNode.js的简介和安装Node.js的简介 Node.js的发明人：Rayn Dahl 我们要树立一个观念，Node.js 不是一门新的语言，还是基于JavaScript进行编程的。 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境 Node 是一个让 JavaScript 运行在服务端的开发平台，它让 JavaScript 成为与PHP、P">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://s1.ax1x.com/2022/12/03/zrV6Q1.jpg">
<meta property="article:published_time" content="2022-12-03T07:48:41.000Z">
<meta property="article:modified_time" content="2022-12-28T14:13:42.393Z">
<meta property="article:author" content="晚夜微雨问海棠">
<meta property="article:tag" content="前端体系">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://s1.ax1x.com/2022/12/03/zrV6Q1.jpg"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="http://example.com/posts/3a5743c3"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//fonts.googleapis.com" crossorigin=""/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="manifest" href="/manifest.json"/><meta name="msapplication-TileColor" content="#49b1f5"/><link rel="apple-touch-icon" sizes="180x180" href="/img/siteicon/128.png"/><link rel="icon" type="image/png" sizes="32x32" href="/img/siteicon/32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/img/siteicon/16.png"/><link rel="mask-icon" href="/img/siteicon/128.png" color="#5bbad5"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;display=swap" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":false,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"简"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":150},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: true
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":650,"languages":{"author":"作者: 晚夜微雨问海棠","link":"链接: ","source":"来源: 晚夜微雨问海棠のBlog","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#1f1f1f","position":"top-right"},
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isAnchor: true
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'Node全栈',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-12-28 22:13:42'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'"> <link rel="stylesheet" href="/swiper/swiper.min.css"> <link rel="stylesheet" href="/swiper/swiperstyle.css"> <link rel="stylesheet" href="/css/rightMenu.css"> <link rel="stylesheet" href="/css/constrain.css"><!-- hexo injector head_end start --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-card-history/baiduhistory/css/main.css"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-categories-card@1.0.0/lib/categorybar.css"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu/lib/clock.min.css" /><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-double-row-display@1.00/cardlistpost.min.css"/>
<style>#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap > .tags:before {content:"\A";
  white-space: pre;}#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap > .tags > .article-meta__separator{display:none}</style>
<link rel="stylesheet" href="https://cdn.cbd.int/anzhiyu-blog@2.0.3/css/runtime/runtime.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/swiper.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/swiperstyle.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-wowjs/lib/animate.min.css" media="print" onload="this.media='screen'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/assets/font-awesome-animation.min.css" media="defer" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/tag_plugins.css" media="defer" onload="this.media='all'"><script src="https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/assets/carousel-touch.js"></script><!-- hexo injector head_end end --><meta name="generator" content="Hexo 6.2.0"><link rel="alternate" href="/atom.xml" title="晚夜微雨问海棠のBlog" type="application/atom+xml">
</head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><div id="web_bg" style="background:url(https://s1.ax1x.com/2022/12/03/zrV6Q1.jpg);background-attachment: local;background-position: center;background-size: cover;background-repeat: no-repeat;"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://img2.woyaogexing.com/2022/06/28/de1ce3dc65468fd4!400x400.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">97</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">31</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">17</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/bangumis/index.html"><i class="fa-fw fas fa-home"></i><span> 追番</span></a></div><div class="menus_item"><a class="site-page" href="/comments/"><i class="fa-fw fas fa-envelope"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 生活馆</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" target="_blank" rel="noopener" href="http://81.69.189.243:8082/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友情链接</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://s1.ax1x.com/2022/12/03/zrV6Q1.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">晚夜微雨问海棠のBlog</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/bangumis/index.html"><i class="fa-fw fas fa-home"></i><span> 追番</span></a></div><div class="menus_item"><a class="site-page" href="/comments/"><i class="fa-fw fas fa-envelope"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 生活馆</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" target="_blank" rel="noopener" href="http://81.69.189.243:8082/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友情链接</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">Node全栈</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-12-03T07:48:41.000Z" title="发表于 2022-12-03 15:48:41">2022-12-03</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-12-28T14:13:42.393Z" title="更新于 2022-12-28 22:13:42">2022-12-28</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">19.8k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>80分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="Node全栈"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="Node-js"><a href="#Node-js" class="headerlink" title="Node.js"></a>Node.js</h1><h2 id="Node-js的简介和安装"><a href="#Node-js的简介和安装" class="headerlink" title="Node.js的简介和安装"></a>Node.js的简介和安装</h2><h3 id="Node-js的简介"><a href="#Node-js的简介" class="headerlink" title="Node.js的简介"></a>Node.js的简介</h3><ol>
<li>Node.js的发明人：Rayn Dahl</li>
<li>我们要树立一个观念，Node.js 不是一门新的语言，还是基于JavaScript进行编程的。</li>
<li>Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境</li>
<li>Node 是一个让 JavaScript 运行在服务端的开发平台，它让 JavaScript 成为与PHP、Python、Perl、Ruby 等服务端语言平起平坐的脚本语言。 [2]  发布于2009年5月，由Ryan Dahl开发，实质是对Chrome V8引擎进行了封装</li>
</ol>
<h3 id="Node-js-的来历"><a href="#Node-js-的来历" class="headerlink" title="Node.js 的来历"></a>Node.js 的来历</h3><ol>
<li>Rayn Dahl发现：老牌的后端语言，理论上一个8GB的内存可以同时连接用户数量4000个，此时如果想要web应用程序支持更多的用户数量，就需要增加服务器的数量；从web应用程序上讲，硬件成本会变得更高，所以Rayn Dahl就想创造一个平台解决类似的问题，提高性能和并发性，所以结合Chrome的V8引擎创造了Node.js这个平台</li>
</ol>
<h3 id="安装Node-js"><a href="#安装Node-js" class="headerlink" title="安装Node.js"></a>安装Node.js</h3><ol>
<li>Node.js可以安装在windows、mac、linux上，但是语言都是一样的，都是JavaScript，所以说Node.js更像是java的虚拟机，大家只需要写一份语音，就可以同时运行在windows、mac和linux上了</li>
<li>Node.js的中文网：<a target="_blank" rel="noopener" href="http://nodejs.cn/">http://nodejs.cn/</a></li>
<li>根据自己的系统，选择对应的版本，进行下载</li>
<li>如何查看安装成功了</li>
<li>搜索找到cmd，输入node -v查看版本</li>
<li>下面的命令代表查看node.js的版本</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">node -v</span><br></pre></td></tr></table></figure>
<ol>
<li>显示v14.15.3表示当前的Node.js的版本是14.15.3</li>
</ol>
<h2 id="关于CMD命令"><a href="#关于CMD命令" class="headerlink" title="关于CMD命令"></a>关于CMD命令</h2><ol>
<li>什么是cmd命令：cmd英文含义是command（命令）的意思，也就是说在cmd窗口的输入的指令都是对计算机的命令</li>
<li>如何启动cmd命令？</li>
<li>以win10为例，在计算机查找“cmd”，点击打开</li>
<li>此时由于我们安装了nodejs，我们就可以在cmd命令中进行输入对应的node指令</li>
<li>比如我们之前输入的<code>node -v</code>指的就是<code>node</code>的版本指令；</li>
<li>此时我们试着输入其他的<code>exe</code>程序的指令，比如输入<code>QQ</code>后回车会报错误</li>
<li>此时我们知道了，不是所有<code>exe程序</code>都可以在<code>cmd命令</code>中执行，如果想要执行必须在<code>“环境变量”</code>中配置对应的<code>exe程序</code>文件地址</li>
</ol>
<h2 id="计算机的环境变量"><a href="#计算机的环境变量" class="headerlink" title="计算机的环境变量"></a>计算机的环境变量</h2><ol>
<li>任何的操作系统都是有环境变量的（windows、mac、Linux）；</li>
<li>环境变量的作用：在环境变量里面配置的文件夹内部的exe程序，都可以被系统的cmd窗口调用</li>
<li>如果修改环境变量？</li>
<li>以win10为例</li>
<li>在搜索框中输入“环境变量”后打开</li>
<li>找到<code>环境变量</code>打开，找打 <code>path</code>打开，输入目标地址</li>
<li>如何设置系统变量？我们只需要找到计算机中的以c盘为根目录的盘符地址</li>
<li>比如以QQ地址为准找到对应的QQ.exe文件，然后复制对应的地址即可</li>
<li>此时我们再次打开cmd命令输入QQ，此时环境命令生效了</li>
</ol>
<h2 id="Node-js的使用方法"><a href="#Node-js的使用方法" class="headerlink" title="Node.js的使用方法"></a>Node.js的使用方法</h2><h3 id="js的宿主环境"><a href="#js的宿主环境" class="headerlink" title="js的宿主环境"></a>js的宿主环境</h3><ol>
<li>我们在前面了解了Node.js是基于JavaScript进行开发的，所以我们相关的文件是.js文件</li>
<li>我们一定要树立一个认知：js的运行 必须要有宿主环境，否则不能执行</li>
<li>比如我们此时写了一段js代码直接拖拽到浏览器中</li>
<li>你会发现直将源码展示出来了，并没有计算和执行，所以必须要依赖于<code>html文件</code></li>
<li>此时我们创建<code>html文件</code></li>
</ol>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">title</span>&gt;</span>Document<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;01.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>浏览这个HTML文件控制台有输出</li>
<li>所以截止到现在为止我们只学习了一个js的宿主环境，是HTML。</li>
<li>另一个js文件的宿主环境：Node.js平台！</li>
</ol>
<h3 id="关于文件目录位置"><a href="#关于文件目录位置" class="headerlink" title="关于文件目录位置"></a>关于文件目录位置</h3><ol>
<li>我们可以通过cmd命令窗口去执行js文件</li>
<li>此时我们直接打开cmd窗口</li>
<li>光标闪烁的位置指的是当前文件目录下课执行的js文件的位置</li>
<li>此时我们知道js文件在C盘的根目录下的node_study文件夹内部，所以我们要先后退</li>
<li>后退的命令：</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span>..</span><br></pre></td></tr></table></figure>
<ol>
<li>此时也可以使用多级命令</li>
<li>比如</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span>../../../</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们就到的C盘的根目录下</li>
<li>进入到node_study文件夹内部</li>
<li>进入文件命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> 文件夹名</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们可以使用tab进行匹配，比如cd n按tab会智能帮你查找对应符合条件的文件夹或者文件，匹配中按回车</li>
</ol>
<h3 id="Node-js的基本使用"><a href="#Node-js的基本使用" class="headerlink" title="Node.js的基本使用"></a>Node.js的基本使用</h3><ol>
<li>我要到node_study文件夹内部输入</li>
<li>执行命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">node 01.js</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们就知道了要运行哪个文件就<code>node</code>这个文件</li>
<li>补充两个常用的命令</li>
<li>第一个清屏命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cls</span><br></pre></td></tr></table></figure>
<ol>
<li>第二个命令也是常用的命令，如果我们的文件目录层级比较深，每一次去cd或者cd..代价太大了，此时我们可以使用下面命令代替</li>
<li>按住<code>“shift”键</code>不松手，右键后选择“在此处打开<code>Powershell窗口</code></li>
<li>此时你会发现当前的光标位置就直接到了对应的文件目录下</li>
<li>Powershell在我们的工作中是可以满足我们大部分需求的，比如我们node命令都是支持的</li>
</ol>
<h2 id="使用Node-js搭建服务器"><a href="#使用Node-js搭建服务器" class="headerlink" title="使用Node.js搭建服务器"></a>使用Node.js搭建服务器</h2><h3 id="关于demo的搭建"><a href="#关于demo的搭建" class="headerlink" title="关于demo的搭建"></a>关于demo的搭建</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 得到内置模块,引入NodeJS的内置http模块</span></span><br><span class="line"><span class="keyword">var</span> http = <span class="built_in">require</span>(<span class="string">&quot;http&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建服务器，使用createServer方法</span></span><br><span class="line"><span class="comment">// 回调函数中有req参数表示的是请求，res的参数表示的是响应</span></span><br><span class="line"><span class="keyword">var</span> server = http.<span class="title function_">createServer</span>(<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="comment">// 输出</span></span><br><span class="line">  res.<span class="title function_">end</span>(<span class="string">&quot;Hello Mashbing&quot;</span>);</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 监听，默认的端口是80（阿帕奇），所以我们用3000端口</span></span><br><span class="line">server.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我使用node 01.js就能运行这个文件</li>
<li>此时我们不要关闭这个<code>PowerShell</code>或者<code>CMD窗口</code>，输入网址</li>
<li>127.0.0.1:3000</li>
<li>我们使用3000端口开辟我的node通道</li>
<li>打断CMD使用下面的命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ctrl+c</span><br></pre></td></tr></table></figure>
<ol>
<li>我们一定要维持着光标挂起的状态，如果打断了，此时页面就崩溃了</li>
<li>需要注意的是，如果改变这个文件的内容，此时一定要重新进行node执行</li>
<li>有两个问题需要注意一下<ol>
<li>第一个和<code>PHP</code>一样，Node搭建的服务器也是将所有的计算结果扁平化后返回给计算机</li>
<li>第二个是一个没有安装<code>Node.js</code>的计算机进行请求我们本地有<code>Node.js</code>的计算机的时候能不能访问我们的功能？</li>
<li>答案是可以的，因为<code>Node.js</code>本身就是<code>搭建服务器</code>的，所以我们只要把<code>ip</code>给对应在同网络下的计算机都可以访问，因为本质上访问的不是<code>Node</code>，而是<code>服务器</code></li>
</ol>
</li>
</ol>
<h3 id="res-end"><a href="#res-end" class="headerlink" title="res.end()"></a>res.end()</h3><ol>
<li>res.end是不允许输出多行的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输出</span></span><br><span class="line">res.<span class="title function_">end</span>(<span class="string">&quot;你好我是第7行&quot;</span>); <span class="comment">//输出结果</span></span><br><span class="line">res.<span class="title function_">end</span>(<span class="string">&quot;你好我是第2行&quot;</span>);</span><br><span class="line">res.<span class="title function_">end</span>(<span class="string">&quot;你好我是第3行&quot;</span>);</span><br><span class="line">res.<span class="title function_">end</span>(<span class="string">&quot;你好我是第4行&quot;</span>);</span><br><span class="line">res.<span class="title function_">end</span>(<span class="string">&quot;你好我是第5行&quot;</span>);</span><br></pre></td></tr></table></figure>
<ol>
<li>res.end不能输入非字符串</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">res.<span class="title function_">end</span>(<span class="string">&quot;好我是第7行&quot;</span>); <span class="comment">//正确的</span></span><br><span class="line">res.<span class="title function_">end</span>(<span class="number">1234</span>);<span class="comment">//错误的</span></span><br></pre></td></tr></table></figure>
<ol>
<li>res.end是可以结合HTML标签显示的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">res.<span class="title function_">end</span>(<span class="string">&quot;&lt;h1&gt;你好&lt;/h1&gt;&quot;</span>);</span><br></pre></td></tr></table></figure>
<h3 id="res-write"><a href="#res-write" class="headerlink" title="res.write()"></a>res.write()</h3><ol>
<li>如果要使用res.write最后必须要有res.end，否则浏览器处于请求状态</li>
<li>多条语句输出使用的是res.write，并且也结合HTML标签进行使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">res.<span class="title function_">write</span>(<span class="string">&quot;&lt;p&gt;你好我是第1行&lt;/p&gt;&quot;</span>);</span><br><span class="line">res.<span class="title function_">write</span>(<span class="string">&quot;&lt;p&gt;你好我是第2行&lt;/p&gt;&quot;</span>);</span><br><span class="line">res.<span class="title function_">write</span>(<span class="string">&quot;&lt;p&gt;你好我是第3行&lt;/p&gt;&quot;</span>);</span><br><span class="line">res.<span class="title function_">write</span>(<span class="string">&quot;&lt;p&gt;你好我是第4行&lt;/p&gt;&quot;</span>);</span><br><span class="line">res.<span class="title function_">end</span>(<span class="string">&quot;结束了&quot;</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>和res.end一样不能输入非字符串的内容</li>
</ol>
<h2 id="Node-js的内置功能"><a href="#Node-js的内置功能" class="headerlink" title="Node.js的内置功能"></a>Node.js的内置功能</h2><ol>
<li>NodeJS的中文文档：<a target="_blank" rel="noopener" href="http://nodejs.cn/api/">http://nodejs.cn/api/</a></li>
</ol>
<h3 id="fs模块"><a href="#fs模块" class="headerlink" title="fs模块"></a>fs模块</h3><ol>
<li>fs模块最重要的一个功能就是异步读取文件（readFile），第一个参数文件，第二个参数是回调函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">fs.<span class="title function_">readFile</span>(<span class="string">&#x27;文件名&#x27;</span>, <span class="function">(<span class="params">err, data</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">if</span> (err) <span class="keyword">throw</span> err;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(data);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<ol>
<li>我们现在要结合这个方法进行一个页面的读取内容</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> http = <span class="built_in">require</span>(<span class="string">&quot;http&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建服务器</span></span><br><span class="line"><span class="keyword">var</span> server = http.<span class="title function_">createServer</span>(<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  fs.<span class="title function_">readFile</span>(<span class="string">&quot;./public/zhoujielun.html&quot;</span>,<span class="keyword">function</span>(<span class="params">err,data</span>) &#123;</span><br><span class="line">    res.<span class="title function_">end</span>(data)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 监听</span></span><br><span class="line">server.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<h3 id="路由（★）"><a href="#路由（★）" class="headerlink" title="路由（★）"></a>路由（★）</h3><ol>
<li>上面的案例，我无论输入什么<code>URL</code>都会显示zhoujielun.html这个页面</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> server = http.<span class="title function_">createServer</span>(<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  fs.<span class="title function_">readFile</span>(<span class="string">&quot;./public/zhoujielun.html&quot;</span>,<span class="keyword">function</span>(<span class="params">err,data</span>) &#123;</span><br><span class="line">    res.<span class="title function_">end</span>(data)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>注意：这里的路由地址是随便写的，你会发现无论路由什么样，都会显示该页面</li>
<li>此时我们就可以利用这个特性完成我们的路由设计</li>
<li>我们可以通过<code>req.url</code>得到用户输入的<code>URL</code>的地址</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> server = http.<span class="title function_">createServer</span>(<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="comment">// 设置字符集</span></span><br><span class="line">  res.<span class="title function_">setHeader</span>(<span class="string">&quot;Content-Type&quot;</span>,<span class="string">&quot;text/html;charset=UTF8&quot;</span>);</span><br><span class="line">  <span class="keyword">if</span>(req.<span class="property">url</span> === <span class="string">&quot;/star/zhoujielun&quot;</span>) &#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(<span class="string">&quot;./public/zhoujielun.html&quot;</span>,<span class="keyword">function</span>(<span class="params">err,data</span>) &#123;</span><br><span class="line">      res.<span class="title function_">end</span>(data)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span>(req.<span class="property">url</span> === <span class="string">&quot;/star/wanglihong&quot;</span>)&#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(<span class="string">&quot;./public/wanglihong.html&quot;</span>,<span class="keyword">function</span>(<span class="params">err,data</span>) &#123;</span><br><span class="line">      res.<span class="title function_">end</span>(data)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    res.<span class="title function_">end</span>(<span class="string">&quot;无页面显示&quot;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>比如我们访问/star/zhoujielun</li>
<li>再比如我们访问的/star/wanglihong</li>
<li>我们之前的认知是<code>路由即文件夹</code>，但是我们的<code>NodeJS</code>颠覆了我们的认知，通过路由进行页面的读取，这个就是<code>顶层路由设计</code></li>
<li>顶层路由设计：<ol>
<li>物理文件层次和URL是没有任何关系的</li>
<li>NodeJS是可以做顶层路由设计的！一个页面URL是可以自定义的</li>
<li>用户的输入的URL是可以映射任何HTML页面的</li>
</ol>
</li>
<li>现在有很多的大型网站都是这种顶层路由设计的，比如知乎网站</li>
<li>老一代的路由实际都是映射服务器的物理文件夹目录</li>
</ol>
<h3 id="模仿知乎路由的顶层设计"><a href="#模仿知乎路由的顶层设计" class="headerlink" title="模仿知乎路由的顶层设计"></a>模仿知乎路由的顶层设计</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> server = http.<span class="title function_">createServer</span>(<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="comment">// 设置字符集</span></span><br><span class="line">  res.<span class="title function_">setHeader</span>(<span class="string">&quot;Content-Type&quot;</span>,<span class="string">&quot;text/html;charset=UTF8&quot;</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 得到用户的url</span></span><br><span class="line">  <span class="keyword">var</span> url = req.<span class="property">url</span>;</span><br><span class="line">  <span class="comment">// 使用正则表达式进行信息的获取</span></span><br><span class="line">  <span class="keyword">var</span> arr = url.<span class="title function_">match</span>(<span class="regexp">/\/user\/(.+)\/(.+)$/</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(arr)</span><br><span class="line">  <span class="comment">// 如果没有对应的路由地址，抛出错误</span></span><br><span class="line">  <span class="keyword">if</span>(!arr) &#123;</span><br><span class="line">    res.<span class="title function_">end</span>(<span class="string">&quot;&lt;h1&gt;无页面显示&lt;/h1&gt;&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 获取信息</span></span><br><span class="line">  <span class="comment">// 正则的第一项</span></span><br><span class="line">  <span class="keyword">var</span> $<span class="number">1</span> = arr[<span class="number">1</span>];</span><br><span class="line">  <span class="comment">// 正则的第二项</span></span><br><span class="line">  <span class="keyword">var</span> $<span class="number">2</span> = arr[<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 数据模拟</span></span><br><span class="line">  <span class="keyword">var</span> user = &#123;</span><br><span class="line">    <span class="string">&quot;zhoujielun&quot;</span>:<span class="string">&quot;周杰伦&quot;</span>,</span><br><span class="line">    <span class="string">&quot;zhangyi&quot;</span>:<span class="string">&quot;张译&quot;</span>,</span><br><span class="line">    <span class="string">&quot;wujing&quot;</span>:<span class="string">&quot;吴京&quot;</span>,</span><br><span class="line">    <span class="string">&quot;yiyangqianxi&quot;</span>:<span class="string">&quot;易烊千玺&quot;</span>,</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> list = &#123;</span><br><span class="line">    <span class="string">&quot;post&quot;</span>:<span class="string">&quot;文章&quot;</span>,</span><br><span class="line">    <span class="string">&quot;ask&quot;</span>:<span class="string">&quot;提问&quot;</span>,</span><br><span class="line">    <span class="string">&quot;answer&quot;</span>:<span class="string">&quot;回答&quot;</span>,</span><br><span class="line">    <span class="string">&quot;pins&quot;</span>:<span class="string">&quot;想法&quot;</span>,</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 页面返回的内容</span></span><br><span class="line">  res.<span class="title function_">write</span>(<span class="string">&quot;&lt;h1&gt;&quot;</span>+user[$<span class="number">1</span>]+<span class="string">&quot;你好&lt;/h1&gt;&quot;</span>)</span><br><span class="line">  res.<span class="title function_">end</span>(<span class="string">&quot;&lt;h2&gt;欢迎来到&quot;</span>+list[$<span class="number">2</span>]+<span class="string">&quot;版块&lt;/h2&gt;&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>我们就模拟了知乎的路由设计</li>
</ol>
<h3 id="顶层路由设计会遇到的问题"><a href="#顶层路由设计会遇到的问题" class="headerlink" title="顶层路由设计会遇到的问题"></a>顶层路由设计会遇到的问题</h3><ol>
<li>我们请求zhoujielun.html文件为例，路由地址是/star/zhoujielun</li>
<li>页面的内容</li>
</ol>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">title</span>&gt;</span>Document<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span>&gt;</span>你好，我是周杰伦<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">&quot;images/zhoujinlun.jpg&quot;</span> <span class="attr">alt</span>=<span class="string">&quot;&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>通过上面你会发现页面中只有文字的展示，没有图片的展示，但是HTML结构中是有img标签的，为什么不能加载？</li>
<li>答：该图片的url路径是没有物理文件夹的</li>
<li>现在这张图片的真是物理地址是<a target="_blank" rel="noopener" href="http://127.0.0.1:3000/star/images/zhoujinlun.jpg">http://127.0.0.1:3000/star/images/zhoujinlun.jpg</a></li>
<li>但是图片物理存放地址是在C:\node_study\public\images，所以一定不能按需加载</li>
<li>解决办法就是对每一张图片进行请求</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> server = http.<span class="title function_">createServer</span>(<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(req.<span class="property">url</span>)</span><br><span class="line">  <span class="comment">// 设置字符集</span></span><br><span class="line">  res.<span class="title function_">setHeader</span>(<span class="string">&quot;Content-Type&quot;</span>,<span class="string">&quot;text/html;charset=UTF8&quot;</span>);</span><br><span class="line"><span class="comment">//对页面的内容进行请求</span></span><br><span class="line">  <span class="keyword">if</span>(req.<span class="property">url</span> === <span class="string">&quot;/star/zhoujielun&quot;</span>) &#123;</span><br><span class="line">    fs.<span class="title function_">readFile</span>(<span class="string">&quot;./public/zhoujielun.html&quot;</span>,<span class="keyword">function</span>(<span class="params">err,data</span>) &#123;</span><br><span class="line">      res.<span class="title function_">end</span>(data)</span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">//对页面的图片地址进行请求</span></span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span>(req.<span class="property">url</span>==<span class="string">&quot;/star/images/zhoujinlun.jpg&quot;</span>)&#123;</span><br><span class="line">    res.<span class="title function_">setHeader</span>(<span class="string">&quot;Content-Type&quot;</span>,<span class="string">&quot;image/jpg&quot;</span>);</span><br><span class="line">    <span class="comment">// 读取图片</span></span><br><span class="line">    fs.<span class="title function_">readFile</span>(<span class="string">&quot;./public/images/zhoujinlun.jpg&quot;</span>,<span class="keyword">function</span>(<span class="params">err,data</span>)&#123;</span><br><span class="line">      res.<span class="title function_">end</span>(data)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">    res.<span class="title function_">end</span>(<span class="string">&quot;无页面显示&quot;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>问题来了，如果图片的数量很多怎么办？每一张都势必要进行对路由的请求和渲染，也就是要给每一张图片都要开辟路由地址，不仅仅是图片，其他文件也是一样的</li>
<li>解决办法就是我们后面要学习的<code>express</code>的中间件来<code>静态化</code>一个文件夹。目的就是当前的这个文件夹内部的文件自动就有了<code>URL路由</code>，不用每一个都单独设置</li>
<li>需要注意的是使用<code>NodeJS</code>进行请求文件的时候需要设置对应的<code>ContentType</code>，就是<code>文件的请求类型</code></li>
<li>常见的请求类型<ol>
<li>text/html:HTML格式</li>
<li>text/css:CSS格式</li>
<li>text/plain:纯文本格式</li>
<li>text/xml:XML格式</li>
<li>image/gif:gif图片格式</li>
<li>image/jpeg:jpg图片格式</li>
<li>image/png:png图片格式</li>
</ol>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">res.<span class="title function_">setHeader</span>(<span class="string">&quot;Content-Type&quot;</span>,<span class="string">&quot;text/html;charset=UTF8&quot;</span>) <span class="comment">//HTML</span></span><br><span class="line">res.<span class="title function_">setHeader</span>(<span class="string">&quot;Content-Type&quot;</span>,<span class="string">&quot; text/css &quot;</span>) <span class="comment">//CSS</span></span><br><span class="line">res.<span class="title function_">setHeader</span>(<span class="string">&quot;Content-Type&quot;</span>,<span class="string">&quot; image/png &quot;</span>) <span class="comment">//png格式的图片</span></span><br></pre></td></tr></table></figure>
<h2 id="模块（★）"><a href="#模块（★）" class="headerlink" title="模块（★）"></a>模块（★）</h2><ol>
<li>什么是模块？</li>
<li>当一个js文件可以独立完成一个功能的时候，这个js文件就是一个模块；</li>
<li>当一个多个.js文件共同完成一个功能的时候，这个些js文件就是一个模块。</li>
<li>模块就是module（模块的意思）</li>
<li>比如一个round.js文件完成的是对于面积和周长的计算，那么这个.js文件就是一个模块，</li>
</ol>
<h3 id="HTML的多文件引用"><a href="#HTML的多文件引用" class="headerlink" title="HTML的多文件引用"></a>HTML的多文件引用</h3><ol>
<li>HTML的宿主环境中，多一个js文件公用一个html宿主，此时它们的作用域是公用的</li>
</ol>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">title</span>&gt;</span>Document<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;01.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span> →var a = 100</span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;02.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span> →alert(a)</span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line"></span><br><span class="line">  <span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>此时页面中是可以弹出100的，因为此时01.js文件中的a是全局变量也就是window的属性，所以02.js是可以使用window.a的也就是100</li>
</ol>
<h3 id="Node-js的多文件引用"><a href="#Node-js的多文件引用" class="headerlink" title="Node.js的多文件引用"></a>Node.js的多文件引用</h3><blockquote>
<p>┣ app.js</p>
<p>┣ 01.js</p>
</blockquote>
<ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">require</span>(<span class="string">&quot;./01.js&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;app.js文件&quot;</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>01.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;01.js文件&quot;</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>输入命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">node app.js</span><br></pre></td></tr></table></figure>
<ol>
<li>在<code>Node.js</code>中<code>require()</code>引用文件在引用的同时也在执行，所以就能过输入两个文件的内容</li>
</ol>
<h3 id="Node-js中的js文件作用域天生隔离"><a href="#Node-js中的js文件作用域天生隔离" class="headerlink" title="Node.js中的js文件作用域天生隔离"></a>Node.js中的js文件作用域天生隔离</h3><blockquote>
<p>┣ app.js</p>
<p>┣ 01.js</p>
</blockquote>
<ol>
<li>01.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="number">100</span>;</span><br></pre></td></tr></table></figure>
<ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">require</span>(<span class="string">&quot;./01.js&quot;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br></pre></td></tr></table></figure>
<ol>
<li>输入命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">node app.js</span><br></pre></td></tr></table></figure>
<ol>
<li>错误信息内容是a没有被定义</li>
<li><code>js</code>文件在<code>NodeJS</code>中作用域隔离，因为<code>NodeJS</code>没有<code>window对象</code></li>
<li>此时我们想让文件之间能够相互通信，所以需要让文件自己<code>暴露</code></li>
</ol>
<h3 id="exports命令"><a href="#exports命令" class="headerlink" title="exports命令"></a>exports命令</h3><blockquote>
<p>┣ app.js</p>
<p>┣ a.js</p>
</blockquote>
<ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="built_in">require</span>(<span class="string">&quot;./a.js&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 输入a文件的num参数</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="property">num</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>a.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> num = <span class="number">100</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 向外暴露num参数</span></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">num</span> = num;</span><br></pre></td></tr></table></figure>
<ol>
<li>输入命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">node app.js</span><br></pre></td></tr></table></figure>
<ol>
<li>两点建议：</li>
<li>暴露的时候必须是<code>exports.** == **，此时**</code>必须是统一的，必要有<code>差异化</code></li>
<li>正确的方式</li>
<li>a.js文件</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> b = <span class="number">100</span>;</span><br><span class="line"></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">b</span> = b;</span><br></pre></td></tr></table></figure>
<ol>
<li>在app.js引入</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="built_in">require</span>(<span class="string">&quot;./a.js&quot;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="property">b</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>错误的</li>
<li>a.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> b = <span class="number">100</span>;</span><br><span class="line"><span class="built_in">exports</span>.<span class="property">c</span> = b;</span><br></pre></td></tr></table></figure>
<ol>
<li>第二个建议接收文件的时候，文件名是什么就用什么命名</li>
<li>正确的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="built_in">require</span>(<span class="string">&quot;./a.js&quot;</span>);</span><br></pre></td></tr></table></figure>
<ol>
<li>错误的</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">var b = require(<span class="string">&quot;./a.js&quot;</span>);</span><br></pre></td></tr></table></figure>
<ol>
<li>上面两个建议不会违法了不会报错，但是我们还是要求同学们执行统一规范</li>
</ol>
<h3 id="exports的命名空间"><a href="#exports的命名空间" class="headerlink" title="exports的命名空间"></a>exports的命名空间</h3><blockquote>
<p>┣ a.js</p>
<p>┣ app.js</p>
</blockquote>
<ol>
<li>a.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> num = <span class="number">100</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 向外暴露num参数</span></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">num</span> = num;</span><br></pre></td></tr></table></figure>
<ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="built_in">require</span>(<span class="string">&quot;./a.js&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 输入a文件的num参数</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="property">num</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>你会发现，我们在输出<code>a.js文件</code>的<code>num</code>值的时候使用的是<code>a.num</code>，这个<code>a</code>就是<code>exports</code>返回的一个对象</li>
<li>这样做的好处是什么？这种写法天生有自己的<code>命名空间</code></li>
</ol>
<blockquote>
<p>┣ app.js</p>
<p>┣ round.js</p>
<p>┣ rectangle.js</p>
</blockquote>
<ol>
<li>round.js 和rectangle.js都定义了area函数，但是由于我们都各自的命名空间，所以互相不干扰</li>
<li>round.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">area</span>(<span class="params">r</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="number">3.14</span> * r * r</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">exports</span>.<span class="property">area</span> = area;</span><br></pre></td></tr></table></figure>
<ol>
<li>rectangle.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">area</span>(<span class="params">a,b</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> a * b;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">exports</span>.<span class="property">area</span> = area;</span><br></pre></td></tr></table></figure>
<ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> round = <span class="built_in">require</span>(<span class="string">&quot;./round&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> rectangle = <span class="built_in">require</span>(<span class="string">&quot;./rectangle&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(round.<span class="title function_">area</span>(<span class="number">5</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(rectangle.<span class="title function_">area</span>(<span class="number">5</span>,<span class="number">6</span>));</span><br></pre></td></tr></table></figure>
<ol>
<li>我们的exports是可以暴露多个参数的</li>
<li>比如round.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">area</span>(<span class="params">r</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="number">3.14</span> * r * r</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">perimeter</span>(<span class="params">r</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="number">3.14</span> * <span class="number">2</span> * r;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">exports</span>.<span class="property">area</span> = area;</span><br><span class="line"><span class="built_in">exports</span>.<span class="property">perimeter</span> = perimeter;</span><br></pre></td></tr></table></figure>
<h3 id="module-exports命令"><a href="#module-exports命令" class="headerlink" title="module.exports命令"></a>module.exports命令</h3><ol>
<li>当一个js文件仅仅希望暴露一个参数，通常是构造函数，此时我们可以使用module.exports命令进行暴露</li>
</ol>
<blockquote>
<p>┣ app.js</p>
<p>┣ People.js</p>
</blockquote>
<ol>
<li>People.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">People</span>(<span class="params">name,age,sex</span>)&#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">sex</span> = sex;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">People</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHello</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;你好我是&quot;</span>+<span class="variable language_">this</span>.<span class="property">name</span>+<span class="string">&quot;，我是一个&quot;</span>+<span class="variable language_">this</span>.<span class="property">sex</span>+<span class="string">&quot;生，我今年&quot;</span>+<span class="variable language_">this</span>.<span class="property">age</span>+<span class="string">&quot;岁了！&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = <span class="title class_">People</span>;</span><br></pre></td></tr></table></figure>
<ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="title class_">People</span> =  <span class="built_in">require</span>(<span class="string">&quot;./People.js&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> xiaoming = <span class="keyword">new</span> <span class="title class_">People</span>.<span class="title class_">People</span>(<span class="string">&quot;小明&quot;</span>,<span class="number">18</span>,<span class="string">&quot;男&quot;</span>);</span><br><span class="line"></span><br><span class="line">xiaoming.<span class="title function_">sayHello</span>()</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们发现小明在new的时候并没有使用和exports类似的命名空间对象，是因为module.exports默认返回的不是对象而是结果</li>
<li>总结：<ol>
<li><code>u</code> 如果文件中要暴露多个参数，此时需要命名空间使用<code>exports.**</code></li>
<li><code>u</code>如果只有一个参数并且是构造函数使用<code>module.exports.**</code></li>
</ol>
</li>
</ol>
<h3 id="文件夹的使用"><a href="#文件夹的使用" class="headerlink" title="文件夹的使用"></a>文件夹的使用</h3><blockquote>
<p>┣ app.js</p>
<p>│result.js</p>
<p>│┣ round.js</p>
<p>│┣ rectangle.js</p>
<p>│┣ index.js</p>
</blockquote>
<ol>
<li>我们此时将<code>round.js</code>和<code>rectangle.js</code>放到了一个<code>result文件夹</code>内部，被<code>index.js</code>进行整合。</li>
<li>我们<code>index.js</code>文件</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> rectangle = <span class="built_in">require</span>(<span class="string">&quot;./rectangle&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> round = <span class="built_in">require</span>(<span class="string">&quot;./round&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">round</span> = round;</span><br><span class="line"><span class="built_in">exports</span>.<span class="property">rectangle</span> = rectangle;</span><br></pre></td></tr></table></figure>
<ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> result = <span class="built_in">require</span>(<span class="string">&quot;./result&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(result.<span class="property">round</span>.<span class="title function_">area</span>(<span class="number">5</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(result.<span class="property">rectangle</span>.<span class="title function_">perimeter</span>(<span class="number">4</span>,<span class="number">5</span>));</span><br></pre></td></tr></table></figure>
<ol>
<li>如果我们<code>require()</code>没有<code>.js</code>后缀，此时<code>NodeJS</code>会认为我们在引入一个文件夹，并且执行这个文件夹内部的<code>index.js</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> result = <span class="built_in">require</span>(<span class="string">&quot;./result&quot;</span>);</span><br><span class="line">等价于下面的</span><br><span class="line"><span class="keyword">var</span> result = <span class="built_in">require</span>(<span class="string">&quot;./result/index.js&quot;</span>);</span><br></pre></td></tr></table></figure>
<ol>
<li>需要注意的是不能省略<code>./</code></li>
</ol>
<h3 id="node-modules文件夹"><a href="#node-modules文件夹" class="headerlink" title="node_modules文件夹"></a>node_modules文件夹</h3><ol>
<li><code>NodeJS</code>中，如果文件夹内部存放了<code>node_modules</code>文件夹，此时内部的文件引入的时候就不用写<code>./</code>了</li>
</ol>
<blockquote>
<p>┣ app.js</p>
<p>│node_modules</p>
<p>││result.js</p>
<p>││┣ round.js</p>
<p>││┣ rectangle.js</p>
<p>││┣ index.js</p>
</blockquote>
<ol>
<li><code>result</code>文件夹的内容，就是被一个node_modu文件夹包裹了，此时我们引入时候也发生了变化</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> result = <span class="built_in">require</span>(<span class="string">&quot;result&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(result.<span class="property">round</span>.<span class="title function_">area</span>(<span class="number">5</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(result.<span class="property">rectangle</span>.<span class="title function_">perimeter</span>(<span class="number">4</span>,<span class="number">5</span>));</span><br></pre></td></tr></table></figure>
<ol>
<li>总结，如果我们使用<code>require</code>去引入文件，不加./是引入<code>node_modules</code>文件夹内部的文件，否则就是<code>本地其他文件</code></li>
</ol>
<div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center">require</th>
<th style="text-align:center">引用地址</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">require（‘./reqult.js’）</td>
<td style="text-align:center">同目录下面的result.js</td>
</tr>
<tr>
<td style="text-align:center">require（./result）</td>
<td style="text-align:center">同目录下面的result文件夹内部的index.js</td>
</tr>
<tr>
<td style="text-align:center">require（‘result.js’）</td>
<td style="text-align:center">node_modules文件夹内部的result文件夹内部的index.js</td>
</tr>
<tr>
<td style="text-align:center">require(‘reqult.js)</td>
<td style="text-align:center">node_modules文件夹内部的result.js</td>
</tr>
</tbody>
</table>
</div>
<h2 id="npm的基本使用-★"><a href="#npm的基本使用-★" class="headerlink" title="npm的基本使用(★)"></a>npm的基本使用(★)</h2><h3 id="npm的安装"><a href="#npm的安装" class="headerlink" title="npm的安装"></a>npm的安装</h3><ol>
<li>npm是一个全世界范围内模块的分享社区，我们可以免费使用这个社区内别人开发的模块。</li>
<li>我们只关心怎么使用，不用关心如何封装的，因为他们在封装的时候也有可能在引入其他的模块</li>
<li>社区地址：<a target="_blank" rel="noopener" href="https://www.npmjs.com/">https://www.npmjs.com/</a></li>
<li><code>Relied upon by more than 11 million developers worldwide, npm is committed to making JavaScript development elegant, productive, and safe.</code>全世界有超过1100万的开发人员依靠它，npm致力于使JavaScript开发变得优雅、高效和安全。</li>
<li>如何使用，我们只需要再搜索框内部查询你需要模块的关键字</li>
<li>比如我们想让1234567智能转换为<code>大写</code>的</li>
<li>我们就可以搜“大写”</li>
<li>因为我们在安装<code>NodeJS</code>的时候已经帮我们安装了<code>npm包管理器</code>了，所以我们就可以直接使用了；比如我们找到了一个<code>nzh</code>的模块，此时我们需要使用<code>npm命令</code>进行安装<code>npm install</code></li>
<li>此时参考提供的<code>API</code>进行使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> nzh = <span class="built_in">require</span>(<span class="string">&quot;nzh&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(nzh.<span class="property">hk</span>.<span class="title function_">toMoney</span>(<span class="string">&quot;12345678910&quot;</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(nzh.<span class="property">cn</span>.<span class="title function_">toMoney</span>(<span class="string">&quot;12345678910&quot;</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(nzh.<span class="property">cn</span>.<span class="title function_">encodeS</span>(<span class="string">&quot;12345678910&quot;</span>));</span><br></pre></td></tr></table></figure>
<h3 id="小案例：日期转换"><a href="#小案例：日期转换" class="headerlink" title="小案例：日期转换"></a>小案例：日期转换</h3><ol>
<li>我们想根据路由去获取参数从而进行日期的显示</li>
<li>比如路由地址是2021/05/11此时返回的结构就是：庚子年辛巳月甲寅日</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> http = <span class="built_in">require</span>(<span class="string">&quot;http&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> solarLunar = <span class="built_in">require</span>(<span class="string">&quot;solarLunar&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> server = http.<span class="title function_">createServer</span>(<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="comment">// 设置字符集</span></span><br><span class="line">  res.<span class="title function_">setHeader</span>(<span class="string">&quot;Content-Type&quot;</span>,<span class="string">&quot;text/html;charset=UTF8&quot;</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 得到用户的url</span></span><br><span class="line">  <span class="keyword">var</span> url = req.<span class="property">url</span>;</span><br><span class="line">  <span class="comment">// 使用正则表达式进行信息的获取</span></span><br><span class="line">  <span class="keyword">var</span> arr = url.<span class="title function_">match</span>(<span class="regexp">/\/(.+)\/(.+)\/(.+)$/</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(arr)</span><br><span class="line">  <span class="comment">// 如果没有对应的路由地址，抛出错误</span></span><br><span class="line">  <span class="keyword">if</span>(!arr) &#123;</span><br><span class="line">    res.<span class="title function_">end</span>(<span class="string">&quot;&lt;h1&gt;无页面显示&lt;/h1&gt;&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 获取信息</span></span><br><span class="line">  <span class="comment">// 正则的第一项</span></span><br><span class="line">  <span class="keyword">var</span> $<span class="number">1</span> = arr[<span class="number">1</span>];</span><br><span class="line">  <span class="comment">// 正则的第二项</span></span><br><span class="line">  <span class="keyword">var</span> $<span class="number">2</span> = arr[<span class="number">2</span>]</span><br><span class="line">  <span class="comment">// 正则的第二项</span></span><br><span class="line">  <span class="keyword">var</span> $<span class="number">3</span> = arr[<span class="number">3</span>]</span><br><span class="line">  <span class="keyword">var</span> gl = solarLunar.<span class="title function_">solar2lunar</span>($<span class="number">1</span>,$<span class="number">2</span>,$<span class="number">3</span>);</span><br><span class="line">  <span class="keyword">var</span> nl = solarLunar.<span class="title function_">lunar2solar</span>($<span class="number">1</span>,$<span class="number">2</span>,$<span class="number">3</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(nl)</span><br><span class="line">  res.<span class="title function_">end</span>(<span class="string">&quot;&lt;h2&gt;当前公历是：&quot;</span>+gl.<span class="property">gzYear</span>+<span class="string">&quot;年&quot;</span>+gl.<span class="property">gzMonth</span>+<span class="string">&quot;月&quot;</span>+gl.<span class="property">gzDay</span>+<span class="string">&quot;日&lt;/h2&gt;&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">server.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<h3 id="npm的身份证和依赖"><a href="#npm的身份证和依赖" class="headerlink" title="npm的身份证和依赖"></a>npm的身份证和依赖</h3><ol>
<li>我们从<code>npm</code>上下载的<code>node_modules</code>文件夹内容称之为<code>“依赖”；</code></li>
<li>我们可以使用<code>package.json</code>去管理这些依赖，此时我们就需要创建自己的<code>身份证</code></li>
<li>我们在开发项目的时候<code>第一件事</code>就是要<code>创建身份证</code></li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm init</span><br></pre></td></tr></table></figure>
<ol>
<li>此时会填写一些表单信息包括你的名字、版本号、描述、入口文件、测试命令、git仓库、关键词、作者、版权协议</li>
<li>你可以按需回答，也可以<code>直接回车</code>什么都不输入</li>
<li>此时就完成了创建</li>
<li>内容</li>
</ol>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;yy&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;马士兵教育&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;main&quot;</span><span class="punctuation">:</span> <span class="string">&quot;app.js&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;test&quot;</span><span class="punctuation">:</span> <span class="string">&quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;keywords&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;你好，NodeJS&quot;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;author&quot;</span><span class="punctuation">:</span> <span class="string">&quot;你好&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;license&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ISC&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>有了这个身份证后，以后<code>安装依赖</code>的时候要加<code>--save</code></li>
<li>比如我们装<code>nzh模块</code></li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save nzh</span><br></pre></td></tr></table></figure>
<ol>
<li>再看身份证</li>
</ol>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;yy&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;马士兵教育&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;main&quot;</span><span class="punctuation">:</span> <span class="string">&quot;app.js&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;test&quot;</span><span class="punctuation">:</span> <span class="string">&quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;keywords&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;你好，NodeJS&quot;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;author&quot;</span><span class="punctuation">:</span> <span class="string">&quot;你好&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;license&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ISC&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;dependencies&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;nzh&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^1.0.4&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>为什么要这样做？</li>
<li>我们知道<code>node_modules</code>都是<code>相互依赖</code>的，所以如果引入的模块特别多，此时如果进行物理文件传输的时候会造成特别大，特别碎的文件内容，可以不传这个<code>node_modules文件夹</code>，<code>只传身份证</code>；所以一定要用<code>身份证保存</code>，下一次进行使用的之前，<code>重新安装</code></li>
<li>以后你只要在对应的<code>package.json</code>目录下输入</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm isntall</span><br></pre></td></tr></table></figure>
<ol>
<li>此时<code>NodeJS</code>和<code>npm</code>就会检索对应目录下面的<code>package.json</code>文件内部的<code>dependencies</code>的<code>依赖项</code>然后进行安装</li>
</ol>
<h2 id="淘宝镜像"><a href="#淘宝镜像" class="headerlink" title="淘宝镜像"></a>淘宝镜像</h2><ol>
<li>淘宝做了一个<code>npm</code>的镜像<code>cnpm</code></li>
<li><code>cnpm</code>具有和<code>npm</code>一样的功能</li>
<li>网址:<code>npm.taobao.org</code></li>
<li>安装很简单一行命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g cnpm --registry=https://registry.npm.taobao.org</span><br></pre></td></tr></table></figure>
<ol>
<li>安装成功后就可以使用<code>cnpm</code>去安装模块</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install --save nzh</span><br></pre></td></tr></table></figure>
<h2 id="Express框架"><a href="#Express框架" class="headerlink" title="Express框架"></a>Express框架</h2><ol>
<li>我们为什么要学习<code>Express</code>这个框架？</li>
<li>我们再前一天的课程中，发现使用NodeJS开发的时候是有一些弊端的</li>
<li>请求服务的时候不方便，比如URL的匹配不方便；对于静态页面和文件请求不方便等等。</li>
<li><code>Express</code>简化了关于<code>NodeJS</code>应用的开发</li>
<li>官网地址：<a target="_blank" rel="noopener" href="https://www.expressjs.com.cn/">https://www.expressjs.com.cn/</a></li>
<li>如何安装？</li>
<li>使用<code>npm</code>或者<code>cnpm</code>安装即可</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install –save express</span><br></pre></td></tr></table></figure>
<h3 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a>基本使用</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;你好我是Express框架&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>上代码的结构，就是<code>Express</code>的基本结构</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"></span><br><span class="line">罗列中间件请求内容</span><br><span class="line">罗列中间件请求内容</span><br><span class="line">罗列中间件请求内容</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>我们引入<code>express</code>之后，这个<code>express</code>就是一个函数，调用这个函数就可以创建一个对象，这个对象里面封装了所有的<code>express</code>的方法，需要注意的是，一个程序只能有一个对象</li>
</ol>
<h3 id="中间件"><a href="#中间件" class="headerlink" title="中间件"></a>中间件</h3><h4 id="什么是中间件"><a href="#什么是中间件" class="headerlink" title="什么是中间件"></a>什么是中间件</h4><ol>
<li>中间件就是所谓的HTTP的请求</li>
<li>中间件所干的事情就是用户访问页面的时候当前这次请求的处理事件</li>
<li>我们现在可以使用请求方式来处理不同的事情，在同一个路由地址的情况下</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;我是GET请求&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">post</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;你好我是POST请求&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<h4 id="中间件的路径"><a href="#中间件的路径" class="headerlink" title="中间件的路径"></a>中间件的路径</h4><ol>
<li>我们在之前使用原生<code>NodeJS</code>的时候发现路由的匹配是很精确的，比如<code>/yy</code>此时路由地址是<code>/yy?name=小明</code>，此时由于没有精确匹配不会显示页面</li>
<li>但是<code>express</code>帮我们封装了对应参数集合，匹配的只是路由的主干体</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/yy&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;马士兵&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>下面的URL都是可以直接进入访问这个路由内容的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">http</span>:<span class="comment">//127.0.0.1:3000/yy?name=小明</span></span><br><span class="line"><span class="attr">http</span>:<span class="comment">//127.0.0.1:3000/yy/</span></span><br><span class="line"><span class="attr">http</span>:<span class="comment">//127.0.0.1:3000/yy?name=小明&amp;id=12314</span></span><br></pre></td></tr></table></figure>
<h4 id="中间件的通配符"><a href="#中间件的通配符" class="headerlink" title="中间件的通配符"></a>中间件的通配符</h4><ol>
<li><code>express</code>使用：来匹配路由地址，我们可以通过<code>req.params.**</code>来获取这个参数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/:name/:id&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="keyword">var</span> name = req.<span class="property">params</span>.<span class="property">name</span>;</span><br><span class="line">  <span class="keyword">var</span> id = req.<span class="property">params</span>.<span class="property">id</span>;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;马士兵教育你好，我是&quot;</span>+name+<span class="string">&quot;，我的学号为&quot;</span>+id)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们就省略了自己的正则匹配了</li>
<li>还有一个通配符是<code>*</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;*&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;无页面&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li><code>*</code>匹配的是任何，表示的是匹配任何的页面地址，一般用来做路由的重定向，或者是抛出无页面的显示</li>
</ol>
<h4 id="中间件的顺序"><a href="#中间件的顺序" class="headerlink" title="中间件的顺序"></a>中间件的顺序</h4><ol>
<li>所有的中间件是必须要有顺序的，此时如果我们的中间件内容会匹配多个，此时如果不“放行”，会进行拦截。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/xiaogang/10002&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;&lt;h1&gt;我是小刚，我的学号是10002，我的身份是班长&lt;/h1&gt;&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/:name/:id&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="keyword">let</span> name = req.<span class="property">params</span>.<span class="property">name</span>;</span><br><span class="line">  <span class="keyword">let</span> id = req.<span class="property">params</span>.<span class="property">id</span>;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;&lt;h1&gt;我是&quot;</span>+name+<span class="string">&quot;，我的学号是&quot;</span>+id+<span class="string">&quot;，我的身份是学生&lt;/h1&gt;&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>此时如果页面的路由地址是<code>/xiaogang/10002</code>会返回第一个中间件的内容，第二个中间件虽然也符合匹配条件，但是不会再输出内容， 因为拦截了</li>
</ol>
<h4 id="next-方法"><a href="#next-方法" class="headerlink" title="next()方法"></a>next()方法</h4><ol>
<li>当一个中间件内容匹配了之后我们此时想让其他的中间件继续进行匹配，此时可以使用next()进行放行</li>
<li>我们可以模拟匹配多个路由，此时我们在第一个中间件中进行一个计数器的设置，然后第二个中间件中显示这个结果</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> num = <span class="number">0</span>;</span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/xiaogang/10002&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res,next</span>)&#123;</span><br><span class="line">  num ++;</span><br><span class="line">  <span class="title function_">next</span>()</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/:name/:id&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="keyword">let</span> name = req.<span class="property">params</span>.<span class="property">name</span>;</span><br><span class="line">  <span class="keyword">let</span> id = req.<span class="property">params</span>.<span class="property">id</span>;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;&lt;h1&gt;我是&quot;</span>+name+<span class="string">&quot;，我的学号是&quot;</span>+id+<span class="string">&quot;，计数器&quot;</span>+num+<span class="string">&quot;&lt;/h1&gt;&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>num的数值也会递增</li>
</ol>
<h3 id="输出"><a href="#输出" class="headerlink" title="输出"></a>输出</h3><ol>
<li>下面所有的输出方法，都不需要我们自己写<code>setHeader()</code>，会帮你自动带上<code>Content-type</code></li>
<li>如果输出文案或者包含文件的<code>HTML</code>结构体使用<code>res.send()</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;&lt;h1&gt;马士兵教育&lt;/h1&gt;&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>如果输出的是<code>JSON</code>格式，可以使用<code>res.json()</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line"></span><br><span class="line">  res.<span class="title function_">json</span>(&#123;<span class="string">&quot;a&quot;</span>:<span class="number">1</span>,<span class="string">&quot;b&quot;</span>:<span class="number">2</span>,<span class="string">&quot;c&quot;</span>:[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]&#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>如果输出的内容是<code>JSONP</code>，此时使用<code>res.jsonp()</code>来输出，此时<code>express</code>会自动检测<code>callback</code>的请求参数自动封装对应的函数执行结果</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">jsonp</span>(&#123;<span class="string">&quot;a&quot;</span>:<span class="number">1</span>,<span class="string">&quot;b&quot;</span>:<span class="number">2</span>,<span class="string">&quot;c&quot;</span>:[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>],<span class="string">&quot;d&quot;</span>:&#123;<span class="string">&quot;e&quot;</span>:<span class="number">678</span>&#125;&#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>如果请求的是一个外置的页面，此时要用<code>sendFile()</code>，需要注意是一定要使用绝对路径</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="comment">// __dirname指的是当前文件的所在路径</span></span><br><span class="line">  res.<span class="title function_">sendFile</span>(__dirname+<span class="string">&quot;/public/index.html&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>如果想要跳转页面，可以使用<code>res.redirect()</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line"></span><br><span class="line">  res.<span class="title function_">redirect</span>(<span class="string">&quot;http://www.yy.com&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h3 id="文件夹的静态化"><a href="#文件夹的静态化" class="headerlink" title="文件夹的静态化"></a>文件夹的静态化</h3><ol>
<li>我们在学习原生<code>NodeJS</code>的时候所有的文件请求，都必须设定一次<code>url</code>的匹配，很不方便</li>
<li><code>express</code>提供一个<code>“静态化”</code>的功能，指的是改静态化了文件夹，此时自动拥有路由</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">use</span>(express.<span class="title function_">static</span>(<span class="string">&quot;需要静态化的文件夹名称&quot;</span>))</span><br></pre></td></tr></table></figure>
<blockquote>
<p>┣ app.js</p>
<p>│public</p>
<p>│┣ index.html</p>
<p>││┣ yy.png</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line">app.<span class="title function_">use</span>(express.<span class="title function_">static</span>(<span class="string">&quot;public&quot;</span>));</span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们的静态化路由地址也是可以自定义的</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line">app.<span class="title function_">use</span>(<span class="string">&quot;/wenjianjia&quot;</span>,express.<span class="title function_">static</span>(<span class="string">&quot;public&quot;</span>));</span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<h2 id="Express的请求"><a href="#Express的请求" class="headerlink" title="Express的请求"></a>Express的请求</h2><h3 id="GET请求"><a href="#GET请求" class="headerlink" title="GET请求"></a>GET请求</h3><ol>
<li><code>GET</code>请求识别参数实际上就是解析<code>URL</code>地址的参数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/get_data&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(req.<span class="property">url</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>我们可以使用<code>url</code>内置模块进行处理</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/get_data&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="keyword">var</span> queryData = url.<span class="title function_">parse</span>(req.<span class="property">url</span>,<span class="literal">true</span>).<span class="property">query</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(queryData)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li><code>url.parse</code>方法是用来处理<code>url</code>请求参数的</li>
<li><code>req.url</code>表示的是当前<code>url</code>地址的参数</li>
<li><code>true</code>表示的是对<code>url</code>的解析结果，如果为<code>true</code>解析结果的<code>query</code>就是一个<code>JSON</code>数据，否则就是<code>url</code>的字符串参数</li>
</ol>
<h3 id="POST请求"><a href="#POST请求" class="headerlink" title="POST请求"></a>POST请求</h3><ol>
<li><code>POST请求</code>参数是携带在上行报文上的，所以我们不能使用<code>url模块</code>再去处理了</li>
<li>此时我们可以借助<code>npm模块</code>帮我们处理</li>
<li>安装依赖</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install --save formidable</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 处理post请求</span></span><br><span class="line">app.<span class="title function_">post</span>(<span class="string">&quot;/sub_data&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="comment">// formidable对象内部有个IncomingForm方法，一旦被new调用后会返回表单处理工具的实例</span></span><br><span class="line">  <span class="keyword">var</span> form = <span class="keyword">new</span> formidable.<span class="title class_">IncomingForm</span>();</span><br><span class="line"></span><br><span class="line">  <span class="comment">// err是错误信息，fields表示的是数据源，files表示的是文件源</span></span><br><span class="line">  form.<span class="title function_">parse</span>(req,<span class="keyword">function</span>(<span class="params">err,fields,files</span>)&#123;</span><br><span class="line">    res.<span class="title function_">json</span>(&#123;<span class="string">&quot;result&quot;</span>:<span class="string">&quot;success&quot;</span>&#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>总结一下GET和POST请的处理参数的方法<ol>
<li><code>GET请求</code>是利用<code>NodeJS</code>的内置<code>url</code>模块去处理的，使用<code>url.parse()</code>方法</li>
<li><code>POST请求</code>是利用<code>npm</code> 的<code>formidable</code>模块去处理的，通过<code>IncomingForm()</code>方法进行实例化产生表单处理工具的实例</li>
</ol>
</li>
</ol>
<h3 id="其他方式的请求"><a href="#其他方式的请求" class="headerlink" title="其他方式的请求"></a>其他方式的请求</h3><ol>
<li>我们知道<code>express</code>处理请求一共有二十多种，除了我们常见的<code>GET</code>和<code>POST</code>请求之外，还有其他的请求需要处理参数，其实除了<code>GET</code>请求外，所以的请求处理信息都可以用<code>formidable</code>去处理，方法和<code>POST</code>请求也是一样的</li>
<li>我们以<code>DELETE</code>请求为例</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">delete</span>(<span class="string">&quot;/del_data&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="comment">// formidable对象内部有个IncomingForm方法，一旦被new调用后会返回表单处理工具的实例</span></span><br><span class="line">  <span class="keyword">var</span> form = <span class="keyword">new</span> formidable.<span class="title class_">IncomingForm</span>();</span><br><span class="line"></span><br><span class="line">  <span class="comment">// err是错误信息，fields表示的是数据源，files表示的是文件源</span></span><br><span class="line">  form.<span class="title function_">parse</span>(req,<span class="keyword">function</span>(<span class="params">err,fields,files</span>)&#123;</span><br><span class="line">    <span class="comment">// res.json(&#123;&quot;result&quot;:&quot;success&quot;&#125;)</span></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(fields)</span><br><span class="line">    res.<span class="title function_">send</span>(<span class="string">&quot;学号为&quot;</span>+fields.<span class="property">id</span>+<span class="string">&quot;学生信息删除成功！&quot;</span>);</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="RESTful风格的路由"><a href="#RESTful风格的路由" class="headerlink" title="RESTful风格的路由"></a><strong>RESTful风格的路由</strong></h2><ol>
<li><code>RESTful</code>这个词就表示对页面的功能处理，单词写法就是<code>RESTful</code></li>
<li><code>RESTful</code>就是 <code>REpresentational State Transfer</code> （表现层状态转移）单词的缩写，<code>ful</code>就代表风格</li>
<li><code>RESTful</code>风格路由指的就是用<code>URL</code>表示操作的资源，使用请求方式表示什么操作</li>
<li>我们看一不是<code>RESTful</code>风格路由</li>
</ol>
<div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center">功能</th>
<th style="text-align:center">处理的 URL</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">增加</td>
<td style="text-align:center"><a target="_blank" rel="noopener" href="http://yy.com/add">http://yy.com/add</a></td>
</tr>
<tr>
<td style="text-align:center">删除</td>
<td style="text-align:center"><a target="_blank" rel="noopener" href="http://yy.com/delete">http://yy.com/delete</a></td>
</tr>
<tr>
<td style="text-align:center">修改</td>
<td style="text-align:center"><a target="_blank" rel="noopener" href="http://yy.com/update?id=10001&amp;name=小明">http://yy.com/update?id=10001&amp;name=小明</a></td>
</tr>
<tr>
<td style="text-align:center">查询</td>
<td style="text-align:center"><a target="_blank" rel="noopener" href="http://yy.com/search">http://yy.com/search</a></td>
</tr>
</tbody>
</table>
</div>
<ol>
<li>总结：非<code>RESTful</code>风格的路由是通过<code>URL</code>实际地址去进行操作的区分比如<code>删除</code>和<code>增加</code>路由分别是<code>/delete</code>和<code>/add</code>；但是<code>RESTful</code>风格的路由是通过请求的方式进行区分的，路由不变</li>
</ol>
<h2 id="RESTful风格的TodoList"><a href="#RESTful风格的TodoList" class="headerlink" title="RESTful风格的TodoList"></a>RESTful风格的TodoList</h2><ol>
<li><code>TodoList</code>就是待办事项清单</li>
<li>我们为什么要做这个案例，因为这里面包含了最基本的开发的业务逻辑，增、删、改、查</li>
<li>第一步创建自己的身份证</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm init</span><br></pre></td></tr></table></figure>
<ol>
<li>第二步安装对应依赖，多个依赖可以使用空格隔开</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install –save express formidable</span><br></pre></td></tr></table></figure>
<ol>
<li>我们要写<code>TodoList</code>就必须要先建立基本的模拟数据，用来维护数据的状态</li>
<li>建立一个文件夹<code>database</code>，内部有一个<code>db.js</code>来维护数据</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[&#123;<span class="string">&quot;id&quot;</span>:<span class="number">1</span>,<span class="string">&quot;title&quot;</span>: <span class="string">&quot;吃饭&quot;</span>,<span class="string">&quot;done&quot;</span>: <span class="string">&quot;0&quot;</span>&#125;,&#123;<span class="string">&quot;id&quot;</span>:<span class="number">2</span>,<span class="string">&quot;title&quot;</span>: <span class="string">&quot;睡觉&quot;</span>,<span class="string">&quot;done&quot;</span>: <span class="string">&quot;1&quot;</span>&#125;]</span><br></pre></td></tr></table></figure>
<ol>
<li>创建一个<code>models</code>文件夹，内部创建<code>todo.js</code>文件</li>
<li>这个文件的作用就是向外（使用者）暴露对db.js文件内操作数据的方法</li>
<li>我们先看一个关于路径的问题，我们知道<code>node.js</code>和<code>express</code>都有一个缺点如果没有使用静态化的话，对于路径统一使用绝对路径，所以我们在写引入的时候很不方便，此时我们就可以使用<code>path</code>内置模块帮我们智能合并</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> allTodos = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="comment">// 使用fs模块去读取文件</span></span><br><span class="line">  <span class="comment">// __dirname的作用是智能补充我们的路径地址，因为当前的路径不能以相对路径展示</span></span><br><span class="line">  <span class="comment">// path.resolve()方法表示智能合并路径，实际作用就是将__dirname和后面的相对路径进行智能合并</span></span><br><span class="line">  fs.<span class="title function_">readFile</span>(path.<span class="title function_">resolve</span>(__dirname,<span class="string">&quot;../database/db.js&quot;</span>),<span class="keyword">function</span>(<span class="params">err,data</span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(data)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>我们先进行的是对数据的单元测试</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> path = <span class="built_in">require</span>(<span class="string">&quot;path&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> allTodos = <span class="keyword">function</span>(<span class="params">callback</span>) &#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> result = fs.<span class="title function_">readFile</span>(path.<span class="title function_">resolve</span>(__dirname,<span class="string">&quot;../database/db.js&quot;</span>),<span class="keyword">function</span>(<span class="params">err,data</span>) &#123;</span><br><span class="line">    <span class="title function_">callback</span>(<span class="title class_">JSON</span>.<span class="title function_">stringify</span>(data))</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//单元测试</span></span><br><span class="line"><span class="title function_">allTodos</span>(<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;得到了数据&quot;</span>+<span class="title class_">JSON</span>.<span class="title function_">parse</span>(data))</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>注意上面的回调函数的使用</li>
<li>我们设计了对数据的增、删、改、查的功能</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> path = <span class="built_in">require</span>(<span class="string">&quot;path&quot;</span>);</span><br><span class="line"><span class="comment">// 公用路径</span></span><br><span class="line"><span class="comment">// __dirname的作用是智能补充我们的路径地址，因为当前的路径不能以相对路径展示</span></span><br><span class="line"><span class="comment">// path.resolve()方法表示智能合并路径，实际作用就是将__dirname和后面的相对路径进行智能合并</span></span><br><span class="line"><span class="keyword">var</span> filePath = path.<span class="title function_">resolve</span>(__dirname,<span class="string">&quot;../database/db.js&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// allTodos就是数据源</span></span><br><span class="line"><span class="comment">// 查询数据</span></span><br><span class="line"><span class="keyword">var</span> allTodos = <span class="keyword">function</span>(<span class="params">callback</span>) &#123;</span><br><span class="line">  <span class="comment">// 使用fs模块去读取文件</span></span><br><span class="line">  <span class="keyword">var</span> result = fs.<span class="title function_">readFile</span>(filePath,<span class="keyword">function</span>(<span class="params">err,data</span>) &#123;</span><br><span class="line">    <span class="title function_">callback</span>(<span class="title class_">JSON</span>.<span class="title function_">parse</span>(data.<span class="title function_">toString</span>()))</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 增加数据,机理就是获取所有的数据后，增加对应的数据然后再写入db.js</span></span><br><span class="line"><span class="keyword">var</span> addTodo = <span class="keyword">function</span>(<span class="params">title,callback</span>) &#123;</span><br><span class="line">  <span class="comment">// 增加数据是在已有数据的基础之上进行增加</span></span><br><span class="line">  <span class="comment">// 获取已有数据</span></span><br><span class="line">  <span class="title function_">allTodos</span>(<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> maxId = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; data.<span class="property">length</span>; i++)&#123;</span><br><span class="line">      <span class="keyword">if</span>(data[i].<span class="property">id</span> &gt; maxId) &#123;</span><br><span class="line">        maxId = data[i].<span class="property">id</span>;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 将数据push给data</span></span><br><span class="line">    <span class="keyword">let</span> obj = &#123;<span class="string">&quot;id&quot;</span>: maxId + <span class="number">1</span>, <span class="string">&quot;title&quot;</span>: title, <span class="string">&quot;done&quot;</span>: <span class="string">&quot;0&quot;</span>&#125;;</span><br><span class="line">    data.<span class="title function_">push</span>(obj);</span><br><span class="line">    <span class="comment">// 写入到db.js</span></span><br><span class="line">    <span class="comment">// 第一个参数是写入的地址，第二个参数是文件内容，注意必须是字符</span></span><br><span class="line">    fs.<span class="title function_">writeFile</span>(filePath, <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(data),<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">      <span class="title function_">callback</span>()</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 删除数据，机理就是获取所有的数据后，删除对应id数据然后再写入db.js</span></span><br><span class="line"><span class="keyword">var</span> deleteTode = <span class="keyword">function</span>(<span class="params">id,callback</span>) &#123;</span><br><span class="line">  <span class="title function_">allTodos</span>(<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; data.<span class="property">length</span>; i++)&#123;</span><br><span class="line">      <span class="keyword">if</span>(data[i].<span class="property">id</span> == id) &#123;</span><br><span class="line">        <span class="comment">// 找到对应的下班删除这一项</span></span><br><span class="line">        data.<span class="title function_">splice</span>(i,<span class="number">1</span>)</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 写入</span></span><br><span class="line">    fs.<span class="title function_">writeFile</span>(filePath, <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(data),<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">      <span class="title function_">callback</span>()</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 修改,机理就是获取所有的数据后，修改某一条数据然后再次写入到db.js</span></span><br><span class="line"><span class="keyword">var</span> updateTodo = <span class="keyword">function</span>(<span class="params">id,value,callback</span>) &#123;</span><br><span class="line">  <span class="title function_">allTodos</span>(<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; data.<span class="property">length</span>; i++)&#123;</span><br><span class="line">      <span class="keyword">if</span>(data[i].<span class="property">id</span> == id) &#123;</span><br><span class="line">        data[i].<span class="property">title</span> = value;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">      <span class="comment">// 写入</span></span><br><span class="line">    fs.<span class="title function_">writeFile</span>(filePath, <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(data),<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">      <span class="title function_">callback</span>()</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li><code>app.js</code>的功能，第一步是将文件静态化，目的是要静态化<code>index.html</code>，然后我们要罗列出所有的未办或者已办事项清单</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 引入对数据操作的方法</span></span><br><span class="line"><span class="keyword">var</span> todos = <span class="built_in">require</span>(<span class="string">&quot;./models/todo&quot;</span>);</span><br><span class="line"><span class="comment">// 静态化文件</span></span><br><span class="line">app.<span class="title function_">use</span>(express.<span class="title function_">static</span>(<span class="string">&quot;assets&quot;</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment">// 查询，找出所有的已办和未办的清单</span></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/todolist&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  todos.<span class="title function_">allTodos</span>(<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line"></span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>我们使用 <code>app.js</code> 实际上利用中间件就是制作<code>“接口”</code>，什么是接口？接口就是没有视图的数据源，一般是JSON形式</li>
<li>增加的逻辑很简单，就是用输入框的值，直接调用<code>todos</code>的<code>addTodo</code>方法就可以了</li>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">post</span>(<span class="string">&quot;/todolist&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="keyword">var</span> form = <span class="keyword">new</span> formidable.<span class="title class_">IncomingForm</span>();</span><br><span class="line"></span><br><span class="line">  form.<span class="title function_">parse</span>(req,<span class="keyword">function</span>(<span class="params">err,fields,files</span>)&#123;</span><br><span class="line">    <span class="comment">// 得到用户输入的数据后，要写入db.js</span></span><br><span class="line">    <span class="keyword">var</span> obj = fields;</span><br><span class="line">    todos.<span class="title function_">addTodo</span>(obj.<span class="property">title</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">      res.<span class="title function_">json</span>(&#123;<span class="string">&quot;data&quot;</span>: <span class="string">&quot;success&quot;</span>&#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>index.html</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="string">&quot;#addBtn&quot;</span>).<span class="title function_">click</span>(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">if</span>(!$(<span class="string">&quot;#todoText&quot;</span>).<span class="title function_">val</span>()) &#123;</span><br><span class="line">    <span class="title function_">alert</span>(<span class="string">&quot;请填写数据后提交&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  $.<span class="title function_">post</span>(<span class="string">&quot;/todolist&quot;</span>,&#123;<span class="string">&quot;title&quot;</span>: $(<span class="string">&quot;#todoText&quot;</span>).<span class="title function_">val</span>()&#125;,<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">    <span class="keyword">if</span>(data.<span class="property">data</span> === <span class="string">&#x27;success&#x27;</span>) &#123;</span><br><span class="line">      <span class="title function_">alert</span>(<span class="string">&quot;数据提交成功&quot;</span>)</span><br><span class="line">      <span class="comment">// 清空输入框</span></span><br><span class="line">      $(<span class="string">&quot;#todoText&quot;</span>).<span class="title function_">val</span>(<span class="string">&quot;&quot;</span>);</span><br><span class="line">      <span class="comment">// 重新加载所有的db 数据</span></span><br><span class="line">      <span class="title function_">loadTodos</span>()</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<ol>
<li>删除的逻辑是比较难的，两个困难的，第一个我们如何得动态的<code>li</code>元素？</li>
<li>第二个是我们如何让触发删除方法的元素知道被删除的是谁？</li>
<li>解决如何获取动态元素使用<code>jQuery</code>的事件代理解决</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用事件代理去解决动态节点动态上树的问题，因为初始化页面的时候li标签是得不到的</span></span><br><span class="line">$(<span class="string">&quot;#todoList&quot;</span>).<span class="title function_">delegate</span>(<span class="string">&quot;.itemBtn&quot;</span>,<span class="string">&quot;click&quot;</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="title function_">alert</span>(<span class="string">&quot;我触发了&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>如何让代理知道我要要删除的是谁？答案使用data属性带参数</li>
<li>初始化的时候给<code>button</code>带<code>data-id</code>属性</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="string">&quot;&lt;li&gt;</span></span><br><span class="line"><span class="string">&lt;b&gt;&quot;</span>+item.<span class="property">title</span>+<span class="string">&quot;&lt;/b&gt;</span></span><br><span class="line"><span class="string">&lt;button class=&#x27;itemBtn&#x27; data-id=&quot;</span>+item.<span class="property">id</span>+<span class="string">&quot;&gt;删除&lt;/button&gt;</span></span><br><span class="line"><span class="string">&lt;/li&gt;&quot;</span>);</span><br></pre></td></tr></table></figure>
<ol>
<li>如何获取？</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="variable language_">this</span>).<span class="title function_">data</span>(<span class="string">&quot;id&quot;</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>删除的 功能</li>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 删除todo</span></span><br><span class="line">app.<span class="title function_">delete</span>(<span class="string">&quot;/todolist&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="keyword">var</span> form = <span class="keyword">new</span> formidable.<span class="title class_">IncomingForm</span>();</span><br><span class="line">  form.<span class="title function_">parse</span>(req,<span class="keyword">function</span>(<span class="params">err,fields,files</span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> obj = fields;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="property">id</span>)</span><br><span class="line">    todos.<span class="title function_">deleteTode</span>(obj.<span class="property">id</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">      res.<span class="title function_">json</span>(&#123;<span class="string">&quot;data&quot;</span>: <span class="string">&quot;success&quot;</span>&#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>index.html</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="string">&quot;#todoList&quot;</span>).<span class="title function_">delegate</span>(<span class="string">&quot;.itemBtn&quot;</span>,<span class="string">&quot;click&quot;</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="comment">// 删除db数据</span></span><br><span class="line">  $.<span class="title function_">ajax</span>(&#123;</span><br><span class="line">    <span class="string">&quot;type&quot;</span>:<span class="string">&quot;DELETE&quot;</span>,</span><br><span class="line">    <span class="string">&quot;url&quot;</span>: <span class="string">&quot;/todolist&quot;</span>,</span><br><span class="line">    <span class="string">&quot;data&quot;</span>:&#123;</span><br><span class="line">      <span class="string">&quot;id&quot;</span>: $(<span class="variable language_">this</span>).<span class="title function_">data</span>(<span class="string">&quot;id&quot;</span>) <span class="comment">//携带要删除的id</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="string">&quot;success&quot;</span>:<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">      <span class="keyword">if</span>(data.<span class="property">data</span> == <span class="string">&#x27;success&#x27;</span>)&#123;</span><br><span class="line">        <span class="title function_">alert</span>(<span class="string">&quot;删除成功！&quot;</span>);</span><br><span class="line">        <span class="comment">// 重新加载所有的db 数据</span></span><br><span class="line">        <span class="title function_">loadTodos</span>()</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>修改其实就是在初始化<code>dom</code>的时候增加一个隐藏的<code>input</code>输入框</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="string">&quot;&lt;li&gt;</span></span><br><span class="line"><span class="string">&lt;b&gt;&quot;</span>+item.<span class="property">title</span>+<span class="string">&quot;&lt;/b&gt;</span></span><br><span class="line"><span class="string">&lt;input style=&#x27;display:none&#x27; value=&quot;</span>+item.<span class="property">title</span>+<span class="string">&quot; type=&#x27;text&#x27; &gt;</span></span><br><span class="line"><span class="string">&lt;button class=&#x27;itemBtn&#x27; data-id=&quot;</span>+item.<span class="property">id</span>+<span class="string">&quot;&gt;删除&lt;/button&gt;</span></span><br><span class="line"><span class="string">&lt;/li&gt;&quot;</span>);</span><br></pre></td></tr></table></figure>
<ol>
<li>初始化的时候<code>input</code> 是隐藏的，一旦点击了<code>b</code>标签，<code>b</code>标签隐藏，<code>input</code>标签显示</li>
<li>修改的逻辑</li>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 修改todo</span></span><br><span class="line">app.<span class="title function_">patch</span>(<span class="string">&quot;/todolist&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  <span class="keyword">var</span> form = <span class="keyword">new</span> formidable.<span class="title class_">IncomingForm</span>();</span><br><span class="line">  form.<span class="title function_">parse</span>(req,<span class="keyword">function</span>(<span class="params">err,fields,files</span>)&#123;</span><br><span class="line">    <span class="comment">// 修改数据</span></span><br><span class="line">    <span class="keyword">var</span> obj = fields;</span><br><span class="line">    todos.<span class="title function_">updateTodo</span>(obj.<span class="property">id</span>,obj.<span class="property">value</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">      res.<span class="title function_">json</span>(&#123;</span><br><span class="line">          <span class="string">&quot;status&quot;</span>:<span class="string">&quot;success&quot;</span>,</span><br><span class="line">          <span class="string">&quot;data&quot;</span>: <span class="number">1</span></span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>index.html</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 当patchVal标签失去焦点的时候，b标签显示，发送请求修改db数据</span></span><br><span class="line">$(<span class="string">&quot;#todoList&quot;</span>).<span class="title function_">delegate</span>(<span class="string">&quot;.patchVal&quot;</span>,<span class="string">&quot;blur&quot;</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="comment">// b标签自己隐藏</span></span><br><span class="line">  $(<span class="variable language_">this</span>).<span class="title function_">hide</span>();</span><br><span class="line">  <span class="comment">// 兄弟input 显示</span></span><br><span class="line">  $(<span class="variable language_">this</span>).<span class="title function_">siblings</span>(<span class="string">&quot;b&quot;</span>).<span class="title function_">show</span>();</span><br><span class="line">  <span class="comment">// 通过兄弟标签.itemBtn的data-id获取要修改的db数据id值</span></span><br><span class="line">  <span class="keyword">var</span> id = $(<span class="variable language_">this</span>).<span class="title function_">siblings</span>(<span class="string">&quot;.itemBtn&quot;</span>).<span class="title function_">data</span>(<span class="string">&quot;id&quot;</span>);</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(id,<span class="string">&#x27;id&#x27;</span>)</span><br><span class="line">  <span class="comment">// 发送请求修改已有的数据</span></span><br><span class="line">  $.<span class="title function_">ajax</span>(&#123;</span><br><span class="line">    <span class="string">&quot;type&quot;</span>: <span class="string">&quot;PATCH&quot;</span>,</span><br><span class="line">    <span class="string">&quot;url&quot;</span>: <span class="string">&quot;/todolist&quot;</span>,</span><br><span class="line">    <span class="string">&quot;data&quot;</span>:&#123;</span><br><span class="line">      <span class="string">&quot;id&quot;</span>:id,</span><br><span class="line">      <span class="string">&quot;value&quot;</span>: $(<span class="variable language_">this</span>).<span class="title function_">val</span>()</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="string">&quot;success&quot;</span>: <span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(data,<span class="string">&#x27;data&#x27;</span>)</span><br><span class="line">      <span class="keyword">if</span>(data.<span class="property">status</span> == <span class="string">&quot;success&quot;</span>) &#123;</span><br><span class="line">        <span class="comment">// 重新加载数据</span></span><br><span class="line">        <span class="title function_">loadTodos</span>()</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<ol>
<li>我们将所有的数据进行了一个抽离，将中间件的内容进行了抽离</li>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"><span class="comment">// 引入控制器</span></span><br><span class="line"><span class="keyword">var</span> mainctrl = <span class="built_in">require</span>(<span class="string">&quot;./controllers/mainctrl.js&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 静态化文件</span></span><br><span class="line">app.<span class="title function_">use</span>(express.<span class="title function_">static</span>(<span class="string">&quot;assets&quot;</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment">// 罗列中间件</span></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/todolist&quot;</span>,mainctrl.<span class="property">getTodo</span>); <span class="comment">//查找</span></span><br><span class="line">app.<span class="title function_">post</span>(<span class="string">&quot;/todolist&quot;</span>,mainctrl.<span class="property">addTodo</span>); <span class="comment">//增加</span></span><br><span class="line">app.<span class="title function_">delete</span>(<span class="string">&quot;/todolist&quot;</span>,mainctrl.<span class="property">deleteTode</span>); <span class="comment">//删除</span></span><br><span class="line">app.<span class="title function_">patch</span>(<span class="string">&quot;/todolist&quot;</span>,mainctrl.<span class="property">updateTodo</span>); <span class="comment">//修改</span></span><br><span class="line">app.<span class="title function_">move</span>(<span class="string">&quot;/todolist&quot;</span>,mainctrl.<span class="property">moveData</span>); <span class="comment">//移动</span></span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>)</span><br></pre></td></tr></table></figure>
<ol>
<li>我们将<code>app.js</code>内部的回调函数抽离到了<code>controllers</code>文件夹内部的<code>mainctrl.js</code>文件中了</li>
<li>mainctrl.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 引入对数据操作的方法</span></span><br><span class="line"><span class="keyword">var</span> todos = <span class="built_in">require</span>(<span class="string">&quot;../models/todo&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> formidable = <span class="built_in">require</span>(<span class="string">&quot;formidable&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 查询，找出所有的已办和未办的清单</span></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">getTodo</span> = <span class="keyword">function</span>(<span class="params">res,res</span>)&#123;</span><br><span class="line">  todos.<span class="title function_">allTodos</span>(<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">    <span class="comment">// 将得到的数据返回给前端</span></span><br><span class="line">    res.<span class="title function_">json</span>(&#123;</span><br><span class="line">      <span class="string">&quot;status&quot;</span>:<span class="string">&quot;success&quot;</span>,</span><br><span class="line">      <span class="string">&quot;data&quot;</span>: data</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line">……</span><br></pre></td></tr></table></figure>
<ol>
<li>拖拽的逻辑有一点难，当前我们只做未做清单的拖拽</li>
<li>todo.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 拖拽，startIdx指的是开始的下标，endIdx指的是结束的下标</span></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">moveData</span> = <span class="keyword">function</span>(<span class="params">startIdx,endIdx,callback</span>)&#123;</span><br><span class="line">  <span class="title function_">allTodos</span>(<span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(data,<span class="string">&#x27;data&#x27;</span>)</span><br><span class="line">    <span class="comment">// 改变todos位置，通过startIdx和endIdx</span></span><br><span class="line">    data.<span class="title function_">splice</span>(endIdx,<span class="number">0</span>,data.<span class="title function_">splice</span>(startIdx,<span class="number">1</span>)[<span class="number">0</span>]);</span><br><span class="line">    <span class="comment">// 写入</span></span><br><span class="line">     fs.<span class="title function_">writeFile</span>(filePath, <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(data),<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">      <span class="title function_">callback</span>()</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>index.html</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 拖拽</span></span><br><span class="line">  <span class="comment">// 开始位置的下标和结束位置的下标</span></span><br><span class="line">  <span class="keyword">var</span> sIdx,eIdx;</span><br><span class="line">  $(<span class="string">&quot;#unTodoLists&quot;</span>).<span class="title function_">sortable</span>(&#123;</span><br><span class="line">    <span class="string">&quot;start&quot;</span>:<span class="keyword">function</span>(<span class="params">event,ui</span>)&#123;</span><br><span class="line">      <span class="comment">//得到元素的下班，ui.item指的就是被拖拽的li元素</span></span><br><span class="line">      sIdx = ui.<span class="property">item</span>.<span class="title function_">index</span>();</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="string">&quot;stop&quot;</span>:<span class="keyword">function</span>(<span class="params">event,ui</span>)&#123;</span><br><span class="line">      eIdx = ui.<span class="property">item</span>.<span class="title function_">index</span>();</span><br><span class="line">      $.<span class="title function_">ajax</span>(&#123;</span><br><span class="line">        <span class="string">&quot;type&quot;</span>:<span class="string">&quot;MOVE&quot;</span>,</span><br><span class="line">        <span class="string">&quot;url&quot;</span>:<span class="string">&quot;/todolist&quot;</span>,</span><br><span class="line">        <span class="string">&quot;data&quot;</span>:&#123;</span><br><span class="line">          <span class="string">&quot;sIdx&quot;</span>:sIdx,</span><br><span class="line">          <span class="string">&quot;eIdx&quot;</span>:eIdx</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br></pre></td></tr></table></figure>
<h2 id="MVC架构的介绍"><a href="#MVC架构的介绍" class="headerlink" title="MVC架构的介绍"></a>MVC架构的介绍</h2><p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrVIWd.png" alt=""></p>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrVTSA.png" alt=""></p>
<p>注意：这里有个地方写错了，v-视图，v不是控制器，<br>结构应为：v-视图，c-控制器，m-模型</p>
<ol>
<li>我们上一个案例<code>TodoList</code>是一个标准的<code>MVC</code>架构的编程</li>
<li>无论是<code>MVC</code>还是<code>MVVM</code>都不是设计模式，而是代码的架构层面内容</li>
<li>设计模式指的是解决阶段性问题的，比如我们使用中介者模式只是用来解决某一个类，或者某一段程序的问题。</li>
<li><code>MVC</code>、<code>MVVC</code>是架构层面的，也就是从代码最开始设计时候的组织模式<ol>
<li><code>Model</code>（模型）是应用程序中，处理数据逻辑的部分，通常的作用是和数据库打交道，取数据、处理数据、存数据</li>
<li><code>View</code>（视图）是应用程序中处理数据显示的部分，通常视图的显示结构是依据视图模型设计的。</li>
<li><code>controller</code>（控制器）是应用程序中处理用户的交互部分，通常是从视图层获取数据然后像模型层发送数据</li>
</ol>
</li>
</ol>
<h1 id="MongoDB"><a href="#MongoDB" class="headerlink" title="MongoDB"></a>MongoDB</h1><h2 id="NoSQL的简介"><a href="#NoSQL的简介" class="headerlink" title="NoSQL的简介"></a>NoSQL的简介</h2><ol>
<li>我们在前面的<code>PHP课程</code>中接触过<code>SQL</code>（structured query language 结构化查询语言）</li>
<li><code>SQL</code>数据有一个最大的特点，限制每一个字段的类型</li>
<li>比如我们上面的<code>SQL数据库</code>中的<code>password</code>是<code>varchar</code>（字符串）类型，此时如果由于业务的需要，要将<code>password</code>变为仅<code>int</code>（数字）类型，由于之前的所有数据都是<code>varchar</code>类型，所以拓展性有限</li>
<li><code>NoSQL</code>（Not Only SQL）非结构化数据库</li>
<li>我们看一下什么是<code>非结构化数据</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#123;<span class="string">&quot;id&quot;</span>:<span class="number">10001</span>,<span class="string">&quot;name&quot;</span>:<span class="string">&quot;小明&quot;</span>,<span class="string">&quot;age&quot;</span>:<span class="number">12</span>,<span class="string">&quot;sex&quot;</span>:<span class="string">&quot;男&quot;</span>&#125;,</span><br><span class="line">&#123;<span class="string">&quot;id&quot;</span>:<span class="string">&quot;G1002&quot;</span>,<span class="string">&quot;name&quot;</span>:<span class="string">&quot;小红&quot;</span>,<span class="string">&quot;age&quot;</span>:<span class="number">13</span>,<span class="string">&quot;sex&quot;</span>:<span class="string">&quot;女&quot;</span>,<span class="string">&quot;class&quot;</span>:<span class="string">&quot;3班&quot;</span>,<span class="string">&quot;score&quot;</span>:<span class="number">100</span>&#125;,</span><br></pre></td></tr></table></figure>
<ol>
<li>也就是每一个字段没有限制，比如<code>id</code>可以是数字也可以是字符串，中间互相转换也是允许的，和我们的<code>JavaScript</code>类型</li>
</ol>
<div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center">名称</th>
<th style="text-align:center">优点</th>
<th style="text-align:center">缺点</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">SQL</td>
<td style="text-align:center">适合严格类型的语言，对于查询非常有利</td>
<td style="text-align:center">限制的字段的拓展性</td>
</tr>
<tr>
<td style="text-align:center">NoSQL</td>
<td style="text-align:center">不限制字段类型，每一条数据都有自己的表达形态</td>
<td style="text-align:center">不适用于严格类型的使用</td>
</tr>
</tbody>
</table>
</div>
<h2 id="MongoDB数据库的下载和安装"><a href="#MongoDB数据库的下载和安装" class="headerlink" title="MongoDB数据库的下载和安装"></a>MongoDB数据库的下载和安装</h2><ol>
<li>我们安装的 <code>MongoDB</code> 数据就是<code>NoSQL</code>类型</li>
<li>官网：<a target="_blank" rel="noopener" href="https://www.mongodb.com/">https://www.mongodb.com/</a></li>
</ol>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrVHyt.png" alt=""></p>
<ol>
<li>第二步选择系统和版本</li>
</ol>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrVbOP.png" alt=""></p>
<ol>
<li>下载zip类型</li>
</ol>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrVXTS.png" alt=""></p>
<ol>
<li>然后解压到<code>c盘</code>的<code>Program Files</code>文件夹中</li>
</ol>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrVxYQ.png" alt=""></p>
<ol>
<li>设置对应的环境变量</li>
</ol>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrZpSs.png" alt=""></p>
<ol>
<li>粘贴对应的路径</li>
</ol>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrZ9ln.png" alt=""></p>
<ol>
<li>有可能会遇到缺少补丁的情况，我已经提供了对应的补丁，直接安装就行了</li>
<li>如何查看是否安装成功了</li>
<li>输入下面的命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mongo -version</span><br></pre></td></tr></table></figure>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrZFmV.png" alt=""></p>
<ol>
<li>如果输出了版本号，就说明安装成功了</li>
</ol>
<h2 id="对于Mogo数据库的简单操作"><a href="#对于Mogo数据库的简单操作" class="headerlink" title="对于Mogo数据库的简单操作"></a>对于Mogo数据库的简单操作</h2><ol>
<li><code>mongo</code>数据库也是有可视化图形面板软件的的，但是我们还是前期要学一些简单命令进行操作</li>
</ol>
<div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center">工具</th>
<th style="text-align:center">作用</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">mongod.exe</td>
<td style="text-align:center">负责开机的</td>
</tr>
<tr>
<td style="text-align:center">mongo.exe</td>
<td style="text-align:center">负责管理数据库的</td>
</tr>
</tbody>
</table>
</div>
<ol>
<li>启动数据库（数据库开机）命令</li>
<li>新建一个database文件夹，开启数据库后，会往文件夹中写入很多数据</li>
<li>注意：开启成功后，该命令符窗口，不要关闭，一直保持数据库开机的状态</li>
<li>在新建一个命令符窗口，链接数据库即可使用</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mongod --dbpath c:\database</span><br></pre></td></tr></table></figure>
<ol>
<li>链接数据库，命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mongo</span><br></pre></td></tr></table></figure>
<ol>
<li>创建数据库使用<code>use</code></li>
<li><code>use</code>代表的是使用和创建的意思，如果有该数据库代表的是使用，如果没有则表示创建</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">use yy</span><br></pre></td></tr></table></figure>
<ol>
<li>此时创建并切换到了<code>yy</code>数据库</li>
<li>接下来我们可以在数据库中进行建表</li>
<li>建表和创建数据库一样，如果有代表进入否则代表新建</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.<span class="property">student</span>.<span class="title function_">insert</span>(&#123;<span class="string">&quot;id&quot;</span>:<span class="number">10001</span>,<span class="string">&quot;name&quot;</span>:<span class="string">&quot;小明&quot;</span>,<span class="string">&quot;age&quot;</span>:<span class="number">18</span>,<span class="string">&quot;sex&quot;</span>:<span class="string">&quot;男&quot;</span>&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>此时就代表写入了一条数据</li>
<li>多条数据的写入</li>
<li>可以查看这个集合，<code>find()</code>代表查看所有</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.student.find()</span><br></pre></td></tr></table></figure>
<ol>
<li>条件查询，比如要查找表中所有的男生</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.student.find(&#123;<span class="string">&quot;sex&quot;</span>:<span class="string">&quot;男&quot;</span>&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>此时条件进一步细化，想找到大于18岁的男生</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.student.find(&#123;<span class="string">&quot;sex&quot;</span>:<span class="string">&quot;男&quot;</span> ,<span class="string">&quot;age&quot;</span>:&#123;<span class="string">&quot;<span class="variable">$gt</span>&quot;</span>:18&#125;&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>多条件查询使用逗号隔开，<code>$gt表示大于某个条件,$lt</code>表示小于某个条件</li>
<li>条件在进一步，此时我们要查找年龄大于18岁的男生，或者年龄小于17岁的女生</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.student.find(&#123;<span class="string">&quot;<span class="variable">$or</span>&quot;</span>:[&#123;<span class="string">&quot;sex&quot;</span>:<span class="string">&quot;男&quot;</span>,<span class="string">&quot;age&quot;</span>:&#123;<span class="string">&quot;<span class="variable">$gt</span>&quot;</span>:18&#125;&#125;,&#123;<span class="string">&quot;sex&quot;</span>:<span class="string">&quot;女&quot;</span>,<span class="string">&quot;age&quot;</span>:&#123;<span class="string">&quot;<span class="variable">$lt</span>&quot;</span>:17&#125;&#125;]&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>查看所有的数据库</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">show dbs</span><br></pre></td></tr></table></figure>
<ol>
<li>要想创建数据库必须最少有一条数据</li>
<li>删除数据库</li>
<li>比如我们要删除一个叫做wangerxiao的数据库</li>
<li>第一步必须要先<code>use</code>进去才能删除</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.dropDatabase()</span><br></pre></td></tr></table></figure>
<ol>
<li>如果要查看某一个数据库下面所有的表（集合）</li>
<li>在当前的数据库下输入</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">show collections</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我们要删除一个叫<code>class</code>的表</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.class.drop()</span><br></pre></td></tr></table></figure>
<ol>
<li>我们要删除某一个表中的某一条符合条件的数据</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.student.remove(&#123;<span class="string">&quot;sex&quot;</span>:<span class="string">&quot;男&quot;</span>&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>数据的导入和导出</li>
<li>我们下的最新版本的MongoDB是没有导入和导出的，需要下载对应拓展工具</li>
<li>下载地址：<a target="_blank" rel="noopener" href="https://www.mongodb.com/try/download/database-tools?tck=docs_databasetools">https://www.mongodb.com/try/download/database-tools?tck=docs_databasetools</a></li>
<li>解压后</li>
<li>我们将<code>mongoexport.ext</code>和<code>mongoimport.ext</code>复制下来放到我们的<code>环境变量</code>的<code>bin文件夹</code>内部</li>
<li>此时我们就可以进行导入和导出了</li>
<li>此时需要注意的是，我使用导入和导出的时候不要开启REPL（read eval print loop）环境，也就是不要在<code>mongo命令</code>之后</li>
<li>我们先看导入</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mongoimport -d yy -c student C:\Users\QianchengPC\Desktop\data.txt</span><br></pre></td></tr></table></figure>
<ol>
<li>-d（database）表示的是导入到哪个数据库，-c（collections）表示的是哪个表（集合）</li>
<li>需要注意的是文件的路径不用自己手写，只需要将文件“扥”、“拽”进来即可</li>
<li>看一下导出</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mongoexport -d yy -c student -o C:\Users\QianchengPC\Desktop\beifen.txt</span><br></pre></td></tr></table></figure>
<h2 id="使用mongobooster可视化管理数据库软件"><a href="#使用mongobooster可视化管理数据库软件" class="headerlink" title="使用mongobooster可视化管理数据库软件"></a>使用mongobooster可视化管理数据库软件</h2><ol>
<li>具体使用见博客：<a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_32907195/article/details/109308358">https://blog.csdn.net/qq_32907195/article/details/109308358</a></li>
<li>下载地址：<a target="_blank" rel="noopener" href="https://www.mongobooster.com/downloads">https://www.mongobooster.com/downloads</a></li>
</ol>
<h1 id="Node-js操作MongoDB"><a href="#Node-js操作MongoDB" class="headerlink" title="Node.js操作MongoDB"></a>Node.js操作MongoDB</h1><ol>
<li>我们后面会学习mongoose，所以我们使用NodeJS操作MongoDB，仅仅是为了了解工作原理，更好的学习mongoose</li>
</ol>
<h2 id="连接数据库"><a href="#连接数据库" class="headerlink" title="连接数据库"></a>连接数据库</h2><ol>
<li>要注意两个问题：</li>
<li>第一个问题是我们的版本问题，安装mongodb的时候有版本兼容问题，我们安装的是2.2版本</li>
<li>第二个问题，一定要先开机再进行操作</li>
<li>第一步先安装依赖</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install --save mongodb</span><br></pre></td></tr></table></figure>
<ol>
<li>新建app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="title class_">MongoClient</span> = <span class="built_in">require</span>(<span class="string">&quot;mongodb&quot;</span>).<span class="property">MongoClient</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 数据库的地址，localhost:27017表示的是连接的地址和端口号，/yy表示的是连接的是哪个数据库</span></span><br><span class="line"><span class="keyword">var</span> url = <span class="string">&quot;mongodb://localhost:27017/yy&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// err表示的是错误信息，db表示的是返回信息</span></span><br><span class="line"><span class="title class_">MongoClient</span>.<span class="title function_">connect</span>(url,<span class="keyword">function</span>(<span class="params">err,db</span>)&#123;</span><br><span class="line">  <span class="keyword">if</span>(!err) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;连接成功&quot;</span>)</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;连接失败&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="查询和插入命令"><a href="#查询和插入命令" class="headerlink" title="查询和插入命令"></a>查询和插入命令</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">var MongoClient = require(<span class="string">&quot;mongodb&quot;</span>).MongoClient;</span><br><span class="line"></span><br><span class="line">// 数据库的地址，localhost:27017表示的是连接的地址和端口号，/yy表示的是连接的是哪个数据库</span><br><span class="line">var url = <span class="string">&quot;mongodb://localhost:27017/yy&quot;</span></span><br><span class="line"></span><br><span class="line">// err表示的是错误信息，db表示的是返回信息</span><br><span class="line">MongoClient.connect(url,<span class="keyword">function</span>(err,db)&#123;</span><br><span class="line">  <span class="keyword">if</span>(!err) &#123;</span><br><span class="line">    console.log(<span class="string">&quot;连接成功&quot;</span>)</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    console.log(<span class="string">&quot;连接失败&quot;</span>)</span><br><span class="line">    <span class="built_in">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  // // 查询</span><br><span class="line">  db.collection(<span class="string">&quot;student&quot;</span>).find(&#123;&#125;).toArray(<span class="keyword">function</span>(err,docs)&#123;</span><br><span class="line">    console.log(docs)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">var MongoClient = require(<span class="string">&quot;mongodb&quot;</span>).MongoClient;</span><br><span class="line"></span><br><span class="line">// 数据库的地址，localhost:27017表示的是连接的地址和端口号，/yy表示的是连接的是哪个数据库</span><br><span class="line">var url = <span class="string">&quot;mongodb://localhost:27017/yy&quot;</span></span><br><span class="line"></span><br><span class="line">// err表示的是错误信息，db表示的是返回信息</span><br><span class="line">MongoClient.connect(url,<span class="keyword">function</span>(err,db)&#123;</span><br><span class="line">  <span class="keyword">if</span>(!err) &#123;</span><br><span class="line">    console.log(<span class="string">&quot;连接成功&quot;</span>)</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    console.log(<span class="string">&quot;连接失败&quot;</span>)</span><br><span class="line">    <span class="built_in">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">   // 增加</span><br><span class="line">   db.collection(<span class="string">&quot;student&quot;</span>).insert(&#123;<span class="string">&quot;name&quot;</span>:<span class="string">&quot;小李&quot;</span>,<span class="string">&quot;age&quot;</span>:27&#125;,<span class="keyword">function</span> (err) &#123;</span><br><span class="line">   <span class="keyword">if</span>(!err)&#123;</span><br><span class="line">       console.log(<span class="string">&quot;插入成功了&quot;</span>)</span><br><span class="line">     &#125;</span><br><span class="line">   &#125;)</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<ol>
<li>我们只是了使用<code>node.j</code>s操作<code>MongoDB</code>，实际上问题比较多不推荐</li>
<li>第一个每一个版本的迭代差异化比较大</li>
<li>第二个就是语法设置不利于我们进行大规模的开发，比如我们的MVC编程的设计</li>
</ol>
<h1 id="Mongoose-的使用"><a href="#Mongoose-的使用" class="headerlink" title="Mongoose 的使用"></a>Mongoose 的使用</h1><ol>
<li>官网地址：<a target="_blank" rel="noopener" href="http://www.mongoosejs.net/">http://www.mongoosejs.net/</a></li>
</ol>
<h2 id="基本使用-1"><a href="#基本使用-1" class="headerlink" title="基本使用"></a>基本使用</h2><ol>
<li>我们可以先创建一个<code>models</code>的文件夹，我们在内部创建一个<code>Person</code>的构造函数</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install --save mongoose</span><br></pre></td></tr></table></figure>
<ol>
<li>我们要首先创建一个schema</li>
<li><code>model</code>文件夹内部创建一个<code>Dogs.js</code>文件</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> mongoose = <span class="built_in">require</span>(<span class="string">&quot;mongoose&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建schema，创建数据库表的表头</span></span><br><span class="line"><span class="keyword">var</span> dogSchema = <span class="keyword">new</span> mongoose.<span class="title class_">Schema</span>(&#123;</span><br><span class="line">  <span class="string">&quot;color&quot;</span>  :  <span class="title class_">String</span>,</span><br><span class="line">  <span class="string">&quot;name&quot;</span>:  <span class="title class_">String</span>,</span><br><span class="line">  <span class="string">&quot;age&quot;</span> :  <span class="title class_">Number</span>,</span><br><span class="line">  <span class="string">&quot;sex&quot;</span> :  <span class="title class_">String</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建model，其实底层就是在构造函数</span></span><br><span class="line"><span class="keyword">var</span> <span class="title class_">Dog</span> = mongoose.<span class="title function_">model</span>(<span class="string">&quot;Dog&quot;</span>,dogSchema);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 向外暴露</span></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = <span class="title class_">Dog</span>;</span><br></pre></td></tr></table></figure>
<ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> mongoose = <span class="built_in">require</span>(<span class="string">&quot;mongoose&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 连接数据库</span></span><br><span class="line">mongoose.<span class="title function_">connect</span>(<span class="string">&quot;mongodb://localhost/yy&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 连接我们要使用的model</span></span><br><span class="line"><span class="keyword">var</span> <span class="title class_">Dog</span> = <span class="built_in">require</span>(<span class="string">&quot;./models/Dog.js&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> xiaobai = <span class="keyword">new</span> <span class="title class_">Dog</span>(&#123;</span><br><span class="line">  <span class="string">&quot;id&quot;</span>:   <span class="number">20001</span>,</span><br><span class="line">  <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小白&quot;</span>,</span><br><span class="line">  <span class="string">&quot;age&quot;</span>:  <span class="number">3</span>,</span><br><span class="line">  <span class="string">&quot;sex&quot;</span>:  <span class="string">&quot;女&quot;</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">xiaobai.<span class="title function_">save</span>(<span class="keyword">function</span>(<span class="params">err</span>)&#123;</span><br><span class="line">  <span class="keyword">if</span>(!err)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;插入成功&quot;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>有意思的是数据库中的表会自动帮你转义，比如我们建的名字是dog会帮你加s，为dogs</li>
</ol>
<h2 id="基本操作-增加"><a href="#基本操作-增加" class="headerlink" title="基本操作-增加"></a>基本操作-增加</h2><ol>
<li>方法1</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Dog</span>.<span class="title function_">create</span>(&#123;</span><br><span class="line">  <span class="string">&quot;id&quot;</span>:   <span class="number">20002</span>,</span><br><span class="line">  <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小球&quot;</span>,</span><br><span class="line">  <span class="string">&quot;age&quot;</span>:  <span class="number">2</span>,</span><br><span class="line">  <span class="string">&quot;sex&quot;</span>:  <span class="string">&quot;女&quot;</span></span><br><span class="line">&#125;,<span class="keyword">function</span> (<span class="params">err</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span>(!err)&#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;插入成功&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>方法2</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xiaobai = <span class="keyword">new</span> <span class="title class_">Dog</span>(&#123;</span><br><span class="line">  <span class="string">&quot;id&quot;</span>:   <span class="number">20001</span>,</span><br><span class="line">  <span class="string">&quot;name&quot;</span>: <span class="string">&quot;小白&quot;</span>,</span><br><span class="line">  <span class="string">&quot;age&quot;</span>:  <span class="number">3</span>,</span><br><span class="line">  <span class="string">&quot;sex&quot;</span>:  <span class="string">&quot;女&quot;</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">xiaobai.<span class="title function_">save</span>(<span class="keyword">function</span>(<span class="params">err</span>)&#123;</span><br><span class="line">  <span class="keyword">if</span>(!err)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;插入成功&quot;</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="基本操作-删除"><a href="#基本操作-删除" class="headerlink" title="基本操作-删除"></a>基本操作-删除</h2><ol>
<li>方法1</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Dog</span>.<span class="title function_">find</span>(&#123;<span class="string">&quot;name&quot;</span>:<span class="string">&quot;小球&quot;</span>&#125;,<span class="keyword">function</span> (<span class="params">err,results</span>) &#123;</span><br><span class="line">  results[<span class="number">0</span>].<span class="title function_">remove</span>(<span class="keyword">function</span> (<span class="params">err</span>) &#123;</span><br><span class="line">    !err &amp;&amp; <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;删除成功&quot;</span>)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>删除方法2</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Dog</span>.<span class="title function_">remove</span>(&#123;<span class="string">&quot;name&quot;</span>:<span class="string">&quot;小白&quot;</span>&#125;,<span class="keyword">function</span> (<span class="params">err</span>) &#123;</span><br><span class="line">  !err &amp;&amp; <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;删除成功&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="基本操作-修改"><a href="#基本操作-修改" class="headerlink" title="基本操作-修改"></a>基本操作-修改</h2><ol>
<li>方法1</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Dog</span>.<span class="title function_">find</span>(&#123;<span class="string">&quot;name&quot;</span>:<span class="string">&quot;小球&quot;</span>&#125;,<span class="keyword">function</span> (<span class="params">err,results</span>) &#123;</span><br><span class="line">  <span class="comment">// 返回的是一个数组</span></span><br><span class="line">  <span class="keyword">var</span> temp = results[<span class="number">0</span>];</span><br><span class="line">  <span class="comment">// 修改获取的这一项内容进行修改</span></span><br><span class="line">  temp.<span class="property">name</span> = <span class="string">&quot;小花&quot;</span>;</span><br><span class="line">  <span class="comment">// 修改完毕后进行保存</span></span><br><span class="line">  temp.<span class="title function_">save</span>(<span class="keyword">function</span> (<span class="params">err</span>) &#123;</span><br><span class="line">    !err &amp;&amp; <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;修改成功&quot;</span>)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>方法2</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Dog</span>.<span class="title function_">update</span>(&#123;<span class="string">&quot;name&quot;</span>:<span class="string">&quot;小白&quot;</span>&#125;,&#123;<span class="string">&quot;$set&quot;</span>:&#123;<span class="string">&quot;age&quot;</span>:<span class="number">1</span>&#125;&#125;,<span class="keyword">function</span>(<span class="params">err</span>)&#123;</span><br><span class="line">  !err &amp;&amp; <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;修改成功&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="基本操作-查询"><a href="#基本操作-查询" class="headerlink" title="基本操作-查询"></a>基本操作-查询</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Dog</span>.<span class="title function_">find</span>(&#123;<span class="string">&quot;name&quot;</span>:<span class="string">&quot;小白&quot;</span>&#125;,<span class="keyword">function</span>(<span class="params">err,results</span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(results)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h1 id="Echarts"><a href="#Echarts" class="headerlink" title="Echarts"></a>Echarts</h1><ol>
<li>一个基于 JavaScript 的开源可视化图表库</li>
<li>官网：<a target="_blank" rel="noopener" href="http://echarts.apache.org/zh/index.html">http://echarts.apache.org/zh/index.html</a></li>
</ol>
<h2 id="Echarts的基本使用"><a href="#Echarts的基本使用" class="headerlink" title="Echarts的基本使用"></a>Echarts的基本使用</h2><ol>
<li>学习这种图表很简单，因为它已经提供给了我们很多实例，然后根据我们实际的需求进行复制实例修改就可以了</li>
<li>如果使用<code>npm安装</code>可以使用</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install echarts --save</span><br></pre></td></tr></table></figure>
<ol>
<li>此时我看一个入门案例</li>
</ol>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="comment">// 基于准备好的dom，初始化echarts实例</span></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> myChart = echarts.<span class="title function_">init</span>(<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;main&#x27;</span>));</span></span><br><span class="line"><span class="language-javascript">  <span class="comment">// 指定图表的配置项和数据</span></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> option = &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">title</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">          <span class="attr">text</span>: <span class="string">&quot;我的第一个图表&quot;</span></span></span><br><span class="line"><span class="language-javascript">      &#125;,</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">tooltip</span>: &#123;&#125;,</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">legend</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">          <span class="attr">data</span>:[<span class="string">&#x27;数量&#x27;</span>]</span></span><br><span class="line"><span class="language-javascript">      &#125;,</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">xAxis</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">          <span class="attr">data</span>: [<span class="string">&quot;衬衫&quot;</span>,<span class="string">&quot;羊毛衫&quot;</span>,<span class="string">&quot;雪纺衫&quot;</span>,<span class="string">&quot;裤子&quot;</span>,<span class="string">&quot;高跟鞋&quot;</span>,<span class="string">&quot;袜子&quot;</span>,<span class="string">&quot;羽绒服&quot;</span>]</span></span><br><span class="line"><span class="language-javascript">      &#125;,</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">yAxis</span>: &#123;&#125;,</span></span><br><span class="line"><span class="language-javascript">      <span class="attr">series</span>: [&#123;</span></span><br><span class="line"><span class="language-javascript">          <span class="attr">name</span>: <span class="string">&#x27;数量&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">          <span class="attr">type</span>: <span class="string">&#x27;bar&#x27;</span>,</span></span><br><span class="line"><span class="language-javascript">          <span class="attr">data</span>: [<span class="number">5</span>, <span class="number">20</span>, <span class="number">36</span>, <span class="number">10</span>, <span class="number">10</span>, <span class="number">20</span>,<span class="number">100</span>]</span></span><br><span class="line"><span class="language-javascript">      &#125;]</span></span><br><span class="line"><span class="language-javascript">  &#125;;</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="comment">// 使用刚指定的配置项和数据显示图表。</span></span></span><br><span class="line"><span class="language-javascript">  myChart.<span class="title function_">setOption</span>(option);</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>我们该如何自学Echart？很简单，从实例开始</li>
<li>比如我们现在随便找一个示例</li>
<li>然后点击进入</li>
<li>我们就可以把当前的实例代码复制下来放到自己要使用的地方</li>
<li>此时我们可以根据配置手册进行学习</li>
<li>我们以下面的代码为例</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">option = &#123;</span><br><span class="line">  <span class="attr">tooltip</span>: &#123;</span><br><span class="line">      <span class="attr">trigger</span>: <span class="string">&#x27;item&#x27;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">legend</span>: &#123;</span><br><span class="line">      <span class="attr">top</span>: <span class="string">&#x27;5%&#x27;</span>,</span><br><span class="line">      <span class="attr">left</span>: <span class="string">&#x27;center&#x27;</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">series</span>: [</span><br><span class="line">          &#123;</span><br><span class="line">          <span class="attr">name</span>: <span class="string">&#x27;访问来源&#x27;</span>,</span><br><span class="line">          <span class="attr">type</span>: <span class="string">&#x27;pie&#x27;</span>,</span><br><span class="line">          <span class="attr">radius</span>: [<span class="string">&#x27;40%&#x27;</span>, <span class="string">&#x27;70%&#x27;</span>],</span><br><span class="line">          <span class="attr">avoidLabelOverlap</span>: <span class="literal">false</span>,</span><br><span class="line">          <span class="attr">label</span>: &#123;</span><br><span class="line">              <span class="attr">show</span>: <span class="literal">false</span>,</span><br><span class="line">              <span class="attr">position</span>: <span class="string">&#x27;center&#x27;</span></span><br><span class="line">          &#125;,</span><br><span class="line">          <span class="attr">emphasis</span>: &#123;</span><br><span class="line">              <span class="attr">label</span>: &#123;</span><br><span class="line">                  <span class="attr">show</span>: <span class="literal">true</span>,</span><br><span class="line">                  <span class="attr">fontSize</span>: <span class="string">&#x27;40&#x27;</span>,</span><br><span class="line">                  <span class="attr">fontWeight</span>: <span class="string">&#x27;bold&#x27;</span></span><br><span class="line">              &#125;</span><br><span class="line">          &#125;,</span><br><span class="line">          <span class="attr">labelLine</span>: &#123;</span><br><span class="line">              <span class="attr">show</span>: <span class="literal">false</span></span><br><span class="line">          &#125;,</span><br><span class="line">          <span class="attr">data</span>: [</span><br><span class="line">              &#123;<span class="attr">value</span>: <span class="number">1048</span>, <span class="attr">name</span>: <span class="string">&#x27;搜索引擎&#x27;</span>&#125;,</span><br><span class="line">              &#123;<span class="attr">value</span>: <span class="number">735</span>, <span class="attr">name</span>: <span class="string">&#x27;直接访问&#x27;</span>&#125;,</span><br><span class="line">              &#123;<span class="attr">value</span>: <span class="number">580</span>, <span class="attr">name</span>: <span class="string">&#x27;邮件营销&#x27;</span>&#125;,</span><br><span class="line">              &#123;<span class="attr">value</span>: <span class="number">484</span>, <span class="attr">name</span>: <span class="string">&#x27;联盟广告&#x27;</span>&#125;,</span><br><span class="line">              &#123;<span class="attr">value</span>: <span class="number">300</span>, <span class="attr">name</span>: <span class="string">&#x27;视频广告&#x27;</span>&#125;</span><br><span class="line">          ]</span><br><span class="line">        &#125;</span><br><span class="line">      ]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<ol>
<li>比如我们此时想查看或者学习<code>tootip</code>的配置内容</li>
</ol>
<h1 id="小小调查表单"><a href="#小小调查表单" class="headerlink" title="小小调查表单"></a>小小调查表单</h1><ol>
<li>我们现在从前端的页面的展示，路由，数据库等等的设计都是JavaScript的语言，数据库也是JSON</li>
<li>我们现在要做个前后交互的调查表单</li>
<li>我们的调查内容是“手机流量的统计”</li>
<li>【单选题】：你的手机型号是什么？</li>
<li>【多选题】：你使用手机都喜欢干些什么？打游戏、刷短视频、社交、学习</li>
<li>【数字统计】：你的手机是多少钱</li>
<li>我们第一件事就是静态化一个文件夹</li>
</ol>
<blockquote>
<p>│┣ assets</p>
<p>││┣ lib</p>
<p>│││┣ jquery.js</p>
<p>││┣ result.html</p>
<p>││┣ index.html</p>
<p>│┣ models</p>
<p>││┣ Survey.js</p>
<p>│┣ app.js</p>
</blockquote>
<h2 id="表单提交页面"><a href="#表单提交页面" class="headerlink" title="表单提交页面"></a>表单提交页面</h2><ol>
<li><code>assets/index.html</code>中搭建静态结构，具体页面看<code>index.html</code></li>
<li>提交参数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">selectForm</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">// 用来存储每一项下拉框的值</span></span><br><span class="line">    <span class="keyword">var</span> arr = []</span><br><span class="line">    $(<span class="string">&quot;input[name=subject2]:checked&quot;</span>).<span class="title function_">each</span>(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">      arr.<span class="title function_">push</span>($(<span class="variable language_">this</span>).<span class="title function_">val</span>())</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">return</span> arr</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 切换range 的时候获让视图进行更新</span></span><br><span class="line">  $(<span class="string">&quot;input[name=subject3]&quot;</span>).<span class="title function_">bind</span>(<span class="string">&quot;input&quot;</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="comment">// 选择range条的上一个兄弟b标签，然后设置该元素的值为实时拖拽的range条的值</span></span><br><span class="line">    $(<span class="variable language_">this</span>).<span class="title function_">prev</span>(<span class="string">&quot;b&quot;</span>).<span class="title function_">html</span>($(<span class="variable language_">this</span>).<span class="title function_">val</span>())</span><br><span class="line">  &#125;)</span><br><span class="line">  <span class="comment">// 获取值</span></span><br><span class="line">  $(<span class="string">&quot;#btn&quot;</span>).<span class="title function_">click</span>(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="comment">// 判断用户是否都填写了所有的表单</span></span><br><span class="line">    <span class="keyword">if</span>(!<span class="title function_">selectForm</span>() || !$(<span class="string">&quot;input[name=subject1]:checked&quot;</span>).<span class="title function_">val</span>() || !$(<span class="string">&quot;input[name=subject3]&quot;</span>).<span class="title function_">val</span>()) &#123;</span><br><span class="line">      <span class="title function_">alert</span>(<span class="string">&quot;请完善表单信息&quot;</span>)</span><br><span class="line">      <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    $.<span class="title function_">post</span>(&#123;</span><br><span class="line">      <span class="comment">// 提交数组的时候防止将数组为key</span></span><br><span class="line">      <span class="string">&quot;traditional&quot;</span>: <span class="literal">true</span>,</span><br><span class="line">      <span class="string">&quot;url&quot;</span>:<span class="string">&quot;/form&quot;</span>,</span><br><span class="line">      <span class="string">&quot;data&quot;</span>:&#123;</span><br><span class="line">        <span class="string">&quot;subject1&quot;</span>:$(<span class="string">&quot;input[name=subject1]:checked&quot;</span>).<span class="title function_">val</span>(),<span class="comment">// 获取单选框的值</span></span><br><span class="line">        <span class="string">&quot;subject2&quot;</span>:<span class="title function_">selectForm</span>(),</span><br><span class="line">        <span class="string">&quot;subject3&quot;</span>:$(<span class="string">&quot;input[name=subject3]&quot;</span>).<span class="title function_">val</span>()</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>
<h2 id="app-js路由设计"><a href="#app-js路由设计" class="headerlink" title="app.js路由设计"></a>app.js路由设计</h2><ol>
<li>我们设计完毕<code>index.html</code>页面后，紧接着要设计<code>app.js</code>的中间件</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> formidable = <span class="built_in">require</span>(<span class="string">&quot;formidable&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> mongoose = <span class="built_in">require</span>(<span class="string">&quot;mongoose&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 连接数据库</span></span><br><span class="line">mongoose.<span class="title function_">connect</span>(<span class="string">&quot;mongodb://localhost/yy&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建模型</span></span><br><span class="line"><span class="keyword">var</span> <span class="title class_">Survey</span> = <span class="built_in">require</span>(<span class="string">&quot;./models/Survey.js&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"><span class="comment">// 静态化assets</span></span><br><span class="line">app.<span class="title function_">use</span>(express.<span class="title function_">static</span>(<span class="string">&quot;assets&quot;</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 设计中间件</span></span><br><span class="line">app.<span class="title function_">post</span>(<span class="string">&quot;/form&quot;</span>,<span class="keyword">function</span> (<span class="params">req,res</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> form = <span class="keyword">new</span> formidable.<span class="title class_">IncomingForm</span>();</span><br><span class="line">  form.<span class="title function_">parse</span>(req,<span class="keyword">function</span> (<span class="params">err,fields,files</span>) &#123;</span><br><span class="line">    <span class="title class_">Survey</span>.<span class="title function_">create</span>(&#123;</span><br><span class="line">      <span class="string">&quot;subject1&quot;</span>:fields.<span class="property">subject1</span>,</span><br><span class="line">      <span class="string">&quot;subject2&quot;</span>:fields.<span class="property">subject3</span>,</span><br><span class="line">      <span class="string">&quot;subject3&quot;</span>:fields.<span class="property">subject3</span>,</span><br><span class="line">      <span class="string">&quot;date&quot;</span>: <span class="keyword">new</span> <span class="title class_">Date</span>()</span><br><span class="line">    &#125;,<span class="keyword">function</span>(<span class="params">err</span>)&#123;</span><br><span class="line">      res.<span class="title function_">json</span>(&#123;<span class="string">&quot;success&quot;</span>: err ? <span class="literal">false</span> : <span class="literal">true</span>&#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>);</span><br></pre></td></tr></table></figure>
<h2 id="统计图表页面"><a href="#统计图表页面" class="headerlink" title="统计图表页面"></a>统计图表页面</h2><ol>
<li>我们使用<code>result.html</code>设计统计结果</li>
<li>补充一个MongoDB的命令</li>
<li><code>.count()</code>表示查当前表的统计数量</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">db.surveys.count(&#123;&#125;)</span><br></pre></td></tr></table></figure>
<h1 id="模板引擎"><a href="#模板引擎" class="headerlink" title="模板引擎"></a>模板引擎</h1><ol>
<li>模板引擎的目的就是在固定模板结构中渲染不同的数据，通常是JSON数据</li>
<li>在<code>NodeJS</code>学习的是<code>ejs</code>模板引擎</li>
<li>首先我们要安装<code>ejs</code>依赖</li>
</ol>
<blockquote>
<p>┣ views</p>
<p>│┣ index.ejs</p>
<p>┣ app.js</p>
</blockquote>
<ol>
<li>index.ejs</li>
</ol>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">title</span>&gt;</span>Document<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">h1</span>&gt;</span>你好我叫&lt;%=name%&gt;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span><span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 设置默认的模板引擎为ejs</span></span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">&quot;view engine&quot;</span>,<span class="string">&quot;ejs&quot;</span>);</span><br><span class="line"><span class="comment">// 指的是设置对应的模板引擎文件夹，也就是模板引擎回去固定的文件夹中找ejs文件，默认是views文件夹</span></span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">&quot;views&quot;</span>)</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">render</span>(<span class="string">&quot;index&quot;</span>,&#123;</span><br><span class="line">    <span class="string">&quot;name&quot;</span>:<span class="string">&quot;小明&quot;</span></span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;监听3000端口&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li><p>注意事项</p>
</li>
<li><p><code>views</code>文件夹可以改变，使用下面的语句，在第二个参数设置对应的模板文件夹名称，第一个参数必须是<code>views</code>，</p>
<p>默认不写第二个参数表示模板引擎文件夹为<code>views</code></p>
</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">app.set(<span class="string">&quot;views&quot;</span>,<span class="string">&quot;templates&quot;</span>);</span><br></pre></td></tr></table></figure>
<ol>
<li>模板的拓展名必须是.ejs结尾的文件，但是在<code>render</code>的时候不需要写拓展名</li>
<li>比如我们建了一个<code>login.ejs</code>文件，在下面进行<code>render</code></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">res.<span class="title function_">render</span>(<span class="string">&quot;login&quot;</span>,&#123;</span><br><span class="line">  <span class="string">&quot;xingming&quot;</span>:<span class="string">&quot;小明&quot;</span>,</span><br><span class="line">  <span class="string">&quot;banji&quot;</span>:<span class="string">&quot;三年级&quot;</span>,</span><br><span class="line">  <span class="string">&quot;score&quot;</span>:<span class="string">&quot;495&quot;</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>模板引擎可以使用循环语句</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;h1&gt;</span><br><span class="line">  考试科目：</span><br><span class="line">  &lt;% <span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; kemu.<span class="property">length</span>; i++)&#123; %&gt;</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">span</span>&gt;</span>&lt;%=kemu[i]%&gt;<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line">  &lt;% &#125; %&gt;</span><br><span class="line">&lt;/h1&gt;</span><br></pre></td></tr></table></figure>
<ol>
<li><code>&lt;%%&gt;</code>表示的是设置模板引擎作用域，内部多用于循环和判断语句</li>
<li><code>&lt;%=%&gt;</code>表示的是输出语句</li>
<li>比如下面字典项内容</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">res.<span class="title function_">render</span>(<span class="string">&quot;login&quot;</span>,&#123;</span><br><span class="line">  <span class="string">&quot;xingming&quot;</span>:<span class="string">&quot;小明&quot;</span>,</span><br><span class="line">  <span class="string">&quot;banji&quot;</span>:<span class="string">&quot;三年级&quot;</span>,</span><br><span class="line">  <span class="string">&quot;score&quot;</span>:<span class="string">&quot;495&quot;</span>,</span><br><span class="line">  <span class="string">&quot;kemu&quot;</span> : [<span class="string">&quot;数学&quot;</span>,<span class="string">&quot;语文&quot;</span>,<span class="string">&quot;英语&quot;</span>,<span class="string">&quot;物理&quot;</span>,<span class="string">&quot;化学&quot;</span>]</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h1 id="cookie和session"><a href="#cookie和session" class="headerlink" title="cookie和session"></a>cookie和session</h1><h2 id="cookie"><a href="#cookie" class="headerlink" title="cookie"></a>cookie</h2><ol>
<li>我们知道<code>http</code>是无连接的，每一次请求都需要重新和服务器进行关联和身份识别？服务器怎么知道你是谁？</li>
<li>如何解决这个问题？</li>
<li>第一次请求的时候服务器会下发一个信物（cookie），下一次客户端再请求服务器的时候会携带这个信物，服务器就认识了这个信物，也就完成了身份的识别</li>
<li>下一次浏览器再次发送请求的时候就会携带这个cookie</li>
<li>此时服务器和客户端之间就完成了身份识别问题</li>
<li>服务器会下发一个<code>set-cookie</code>的下行报文字段，今后访问这个服务器的的时候，浏览器都会携带<code>cookie</code>上下行报文上去，这样服务器就完成了身份识别</li>
<li>浏览器的下行响应</li>
<li>下一次的上行请求</li>
<li>如何设置<code>cookie</code>，我们使用<code>express</code>去设置<code>cookie</code>信息</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">res.<span class="title function_">cookie</span>(<span class="string">&quot;visited&quot;</span>,<span class="string">&quot;yy&quot;</span>,&#123;<span class="string">&quot;maxAge&quot;</span>: <span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span> * <span class="number">24</span>&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li><code>&quot;visited&quot;</code>:表示当前cookie信息的key</li>
<li><code>&quot;yy&quot;</code>：表示当前cookie信息的参数value</li>
<li><code>&quot;maxAge&quot;</code>: 表示的是cookie的过期时间</li>
<li>我们在<code>node.js</code>中是用<code>cookie-parser</code>获取<code>cookie</code>信息</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install –-save cookie-parser</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> cookieParser = <span class="built_in">require</span>(<span class="string">&#x27;cookie-parser&#x27;</span>)</span><br><span class="line"><span class="keyword">var</span> app  = <span class="title function_">express</span>();</span><br><span class="line">app.<span class="title function_">use</span>(<span class="title function_">cookieParser</span>())</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(req.<span class="property">cookies</span>)</span><br><span class="line"> res.<span class="title function_">cookie</span>(<span class="string">&quot;visited&quot;</span>,<span class="string">&quot;yy&quot;</span>,&#123;<span class="string">&quot;maxAge&quot;</span>: <span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span> * <span class="number">24</span>&#125;)</span><br><span class="line"> res.<span class="title function_">send</span>(<span class="string">&quot;首页&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;监听3000端口&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="session"><a href="#session" class="headerlink" title="session"></a>session</h2><ol>
<li>我们要知道<code>session</code>是基于<code>cookie</code>的，和<code>cookie</code>不同的是<code>session</code>是存储在服务器端的，而<code>cookie</code>是存储在浏览器端的</li>
<li>看一下<code>cookie</code>和<code>session</code>的区别</li>
</ol>
<blockquote>
<ol>
<li>cookie 和session的区别是：cookie数据保存在客户端，session数据保存在服务器端。</li>
<li>两个都可以用来存私密的东西，同样也都有有效期的bai说法,区别在于session是放在服务器上的，过期与否取决于服务期的设定，cookie是存在客户端的，过去与否可以在cookie生成的时候设置进去。<ol>
<li>cookie数据存放在客户的浏览器上，session数据放在服务器上 ；</li>
<li>cookie不是很安全，别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session ；</li>
<li>session会在一定时间内保存在服务器上。当访问增多，会比较占用你服务器的性能，如果主要考虑到减轻服务器性能方面，应当使用COOKIE ；</li>
<li>单个cookie在客户端的限制是3K，就是说一个站点在客户端存放的COOKIE不能3K；</li>
<li>所以将登陆信息等重要信息存放为SESSION;其他信息如果需要保留，可以放在COOKIE中。</li>
</ol>
</li>
<li>cookie和session的共同之处在于：cookie和session都是用来跟踪浏览器用户身份的会话方式。</li>
<li>cookie 是一种发送到客户浏览器的文本串句柄，并保存在客户机硬盘上，可以用来在某个WEB站点会话间持久的保持数据。</li>
</ol>
</blockquote>
<ol>
<li>我们知道cookie是浏览器端存储的，session是服务器端存储的，session比cookie要安全，主要是session下发的不是明文，而是有这自己规则的随机乱码</li>
<li>我们在express中使用session用的是express-session</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install –-save express-session</span><br></pre></td></tr></table></figure>
<ol>
<li>看一下session的基本使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> session = <span class="built_in">require</span>(<span class="string">&#x27;express-session&#x27;</span>)</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">&#x27;trust proxy&#x27;</span>, <span class="number">1</span>) <span class="comment">// trust first proxy</span></span><br><span class="line">app.<span class="title function_">use</span>(<span class="title function_">session</span>(&#123;</span><br><span class="line">  <span class="attr">secret</span>: <span class="string">&#x27;keyboard cat&#x27;</span>,</span><br><span class="line">  <span class="attr">name</span>:<span class="string">&quot;yy&quot;</span>,</span><br><span class="line">  <span class="attr">resave</span>: <span class="literal">false</span>,</span><br><span class="line">  <span class="attr">saveUninitialized</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">cookie</span>: &#123; <span class="attr">maxAge</span>:<span class="number">86400</span>&#125;,</span><br><span class="line">  <span class="attr">rolling</span>: <span class="number">86400</span></span><br><span class="line">&#125;))</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/:name&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  req.<span class="property">session</span>.<span class="property">name</span> = req.<span class="property">params</span>.<span class="property">name</span>;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;首页&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;3000端口&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>具体的参数解释看下图</li>
</ol>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrZ10K.png" alt=""></p>
<h1 id="制作登录注册页面"><a href="#制作登录注册页面" class="headerlink" title="制作登录注册页面"></a>制作登录注册页面</h1><h2 id="基本的文件夹结构"><a href="#基本的文件夹结构" class="headerlink" title="基本的文件夹结构"></a>基本的文件夹结构</h2><ol>
<li>安装相关的依赖</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install --save express formidable express-session ejs mongoose</span><br></pre></td></tr></table></figure>
<ol>
<li>目录结构</li>
</ol>
<blockquote>
<p>┣ controllers</p>
<p>│┣ registctrl.js</p>
<p>│┣ loginctrl.js</p>
<p>│┣ indexctrl.js</p>
<p>┣ views</p>
<p>│┣ regist.ejs</p>
<p>│┣ index.ejs</p>
<p>│┣ login.ejs</p>
<p>┣ model</p>
<p>│┣ User.js</p>
<p>┣ assets</p>
<p>│┣ css</p>
<p>│┣ js</p>
<p>┣ app.js</p>
</blockquote>
<ol>
<li>准备工作，app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> session = <span class="built_in">require</span>(<span class="string">&quot;express-session&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 设置模板引擎</span></span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">&quot;view engine&quot;</span>,<span class="string">&quot;ejs&quot;</span>)</span><br><span class="line"><span class="comment">// 静态化文件夹</span></span><br><span class="line">app.<span class="title function_">use</span>(express.<span class="title function_">static</span>(<span class="string">&quot;assets&quot;</span>));</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;&lt;h1&gt;首页&lt;/h1&gt;&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用session</span></span><br><span class="line">app.<span class="title function_">set</span>(<span class="string">&#x27;trust proxy&#x27;</span>, <span class="number">1</span>) <span class="comment">// trust first proxy</span></span><br><span class="line">app.<span class="title function_">use</span>(<span class="title function_">session</span>(&#123;</span><br><span class="line">  <span class="attr">secret</span>: <span class="string">&#x27;keyboard cat&#x27;</span>,</span><br><span class="line">  <span class="attr">name</span>:<span class="string">&quot;yy&quot;</span>,</span><br><span class="line">  <span class="attr">resave</span>: <span class="literal">false</span>,</span><br><span class="line">  <span class="attr">saveUninitialized</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">cookie</span>: &#123; <span class="attr">maxAge</span>:<span class="number">86400</span>&#125;,</span><br><span class="line">  <span class="attr">rolling</span>: <span class="number">86400</span></span><br><span class="line">&#125;))</span><br><span class="line"></span><br><span class="line"><span class="comment">// 监听端口</span></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;监听3000端口&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>我们工作的第一步是开辟路由，我们的业务逻辑目前就是登录和注册的业务，所以我们只需要开辟两个路由，首页和注册</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 首页</span></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;&lt;h1&gt;首页&lt;/h1&gt;&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 注册</span></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/regist&quot;</span>,<span class="keyword">function</span>(<span class="params">req,res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">send</span>(<span class="string">&quot;&lt;h1&gt;注册页面&lt;/h1&gt;&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>我们搭建页面使用的是ejs模板引擎，结合bootstrap去搭建结构</li>
</ol>
<h2 id="案例作业"><a href="#案例作业" class="headerlink" title="案例作业"></a>案例作业</h2><ol>
<li><p>我们密码是不应该显示的</p>
</li>
<li><p>我们的作业就是把密码进行加密后传输给后端，后端还可以再次进行加密，存到数据库，这样更安全</p>
<p>推荐加密<code>sha256</code>算法，或者<code>MD5</code>等等都可以</p>
</li>
</ol>
<h1 id="socket"><a href="#socket" class="headerlink" title="socket"></a>socket</h1><ol>
<li>HTTP是无连接的，每一次浏览器都会向服务器发送请求，服务器不会主动向浏览器发送请求，所以我们的微信等等其他的聊天功能都不能用HTTP协议，比如我们如果想用HTTP协议实现“实时通信”，只能是定时器setInterval定时向服务器发送请求，比如我们的体育的图文直播，每一秒钟向服务器发送请求。</li>
<li>我们先来看HTTP协议</li>
</ol>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrZVkF.png" alt=""></p>
<ol>
<li>socket协议是双工通信，服务器和浏览器都可以互相通信</li>
</ol>
<p><img src= "" data-lazy-src="https://s1.ax1x.com/2022/12/03/zrZMOx.png" alt=""></p>
<ol>
<li>websocket就是浏览器端一个双工通信协议，能够实现“实时通信”</li>
<li>使用流行的 web 应用技术栈 —— 比如 LAMP (PHP) —— 来编写聊天应用通常是很困难的。它包含了轮询服务器以检测变化，还要追踪时间戳，并且这种实现是比较慢的。</li>
<li>大多数实时聊天系统通常基于 socke 来构建。 Socket 为客户端和服务器提供了双向通信机制。</li>
<li>这意味着服务器可以 推送 消息给客户端。无论何时你发布一条消息，服务器都可以接收到消息并推送给其他连接到服务器的客户端。</li>
<li>官网：<a target="_blank" rel="noopener" href="https://socket.io/">https://socket.io/</a></li>
<li>可以参考的中文手册：<a target="_blank" rel="noopener" href="https://www.w3cschool.cn/socket/">https://www.w3cschool.cn/socket/</a></li>
</ol>
<h2 id="socket协议实现聊天室"><a href="#socket协议实现聊天室" class="headerlink" title="socket协议实现聊天室"></a>socket协议实现聊天室</h2><blockquote>
<p>┣ app.js</p>
<p>┣ js</p>
<p>│┣ jquery-min.js</p>
<p>┣ index.html</p>
</blockquote>
<ol>
<li>安装express</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save express socket.io</span><br></pre></td></tr></table></figure>
<ol>
<li>创建app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"><span class="keyword">var</span> http = <span class="built_in">require</span>(<span class="string">&#x27;http&#x27;</span>).<span class="title class_">Server</span>(app);</span><br><span class="line"><span class="keyword">var</span> io = <span class="built_in">require</span>(<span class="string">&#x27;socket.io&#x27;</span>)(http);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">use</span>(express.<span class="title function_">static</span>(<span class="string">&quot;js&quot;</span>))</span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&#x27;/&#x27;</span>, <span class="keyword">function</span>(<span class="params">req, res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">sendFile</span>(__dirname + <span class="string">&#x27;/index.html&#x27;</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">io.<span class="title function_">on</span>(<span class="string">&#x27;connection&#x27;</span>, <span class="keyword">function</span>(<span class="params">socket</span>)&#123;</span><br><span class="line">  socket.<span class="title function_">on</span>(<span class="string">&#x27;chat message&#x27;</span>, <span class="keyword">function</span>(<span class="params">msg</span>)&#123;</span><br><span class="line">    io.<span class="title function_">emit</span>(<span class="string">&#x27;chat message&#x27;</span>, msg);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">http.<span class="title function_">listen</span>(<span class="number">3000</span>, <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;listening on *:3000&#x27;</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<ol>
<li>index.html</li>
</ol>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Socket.IO chat<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="language-css"></span></span><br><span class="line"><span class="language-css">      <span class="selector-tag">body</span> &#123; <span class="attribute">margin</span>: <span class="number">0</span>; <span class="attribute">padding-bottom</span>: <span class="number">3rem</span>; <span class="attribute">font-family</span>: -apple-system, BlinkMacSystemFont, <span class="string">&quot;Segoe UI&quot;</span>, Roboto, Helvetica, Arial, sans-serif; &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">      <span class="selector-id">#form</span> &#123; <span class="attribute">background</span>: <span class="built_in">rgba</span>(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.15</span>); <span class="attribute">padding</span>: <span class="number">0.25rem</span>; <span class="attribute">position</span>: fixed; <span class="attribute">bottom</span>: <span class="number">0</span>; <span class="attribute">left</span>: <span class="number">0</span>; <span class="attribute">right</span>: <span class="number">0</span>; <span class="attribute">display</span>: flex; <span class="attribute">height</span>: <span class="number">3rem</span>; <span class="attribute">box-sizing</span>: border-box; backdrop-<span class="attribute">filter</span>: <span class="built_in">blur</span>(<span class="number">10px</span>); &#125;</span></span><br><span class="line"><span class="language-css">      <span class="selector-id">#input</span> &#123; <span class="attribute">border</span>: none; <span class="attribute">padding</span>: <span class="number">0</span> <span class="number">1rem</span>; <span class="attribute">flex-grow</span>: <span class="number">1</span>; <span class="attribute">border-radius</span>: <span class="number">2rem</span>; <span class="attribute">margin</span>: <span class="number">0.25rem</span>; &#125;</span></span><br><span class="line"><span class="language-css">      <span class="selector-id">#input</span><span class="selector-pseudo">:focus</span> &#123; <span class="attribute">outline</span>: none; &#125;</span></span><br><span class="line"><span class="language-css">      <span class="selector-id">#form</span> &gt; <span class="selector-tag">button</span> &#123; <span class="attribute">background</span>: <span class="number">#333</span>; <span class="attribute">border</span>: none; <span class="attribute">padding</span>: <span class="number">0</span> <span class="number">1rem</span>; <span class="attribute">margin</span>: <span class="number">0.25rem</span>; <span class="attribute">border-radius</span>: <span class="number">3px</span>; <span class="attribute">outline</span>: none; <span class="attribute">color</span>: <span class="number">#fff</span>; &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">      <span class="selector-id">#messages</span> &#123; <span class="attribute">list-style-type</span>: none; <span class="attribute">margin</span>: <span class="number">0</span>; <span class="attribute">padding</span>: <span class="number">0</span>; &#125;</span></span><br><span class="line"><span class="language-css">      <span class="selector-id">#messages</span> &gt; <span class="selector-tag">li</span> &#123; <span class="attribute">padding</span>: <span class="number">0.5rem</span> <span class="number">1rem</span>; &#125;</span></span><br><span class="line"><span class="language-css">      <span class="selector-id">#messages</span> &gt; <span class="selector-tag">li</span><span class="selector-pseudo">:nth-child</span>(odd) &#123; <span class="attribute">background</span>: <span class="number">#efefef</span>; &#125;</span></span><br><span class="line"><span class="language-css">    </span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">ul</span> <span class="attr">id</span>=<span class="string">&quot;messages&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">form</span> <span class="attr">id</span>=<span class="string">&quot;form&quot;</span> <span class="attr">action</span>=<span class="string">&quot;&quot;</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">input</span> <span class="attr">id</span>=<span class="string">&quot;input&quot;</span> <span class="attr">autocomplete</span>=<span class="string">&quot;off&quot;</span> /&gt;</span><span class="tag">&lt;<span class="name">button</span>&gt;</span>Send<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;/socket.io/socket.io.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;/jquery.min.js&quot;</span> <span class="attr">rel</span>=<span class="string">&quot;external nofollow&quot;</span> &gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">      $(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">var</span> socket = <span class="title function_">io</span>();</span></span><br><span class="line"><span class="language-javascript">        $(<span class="string">&#x27;form&#x27;</span>).<span class="title function_">submit</span>(<span class="keyword">function</span>(<span class="params"></span>)&#123;</span></span><br><span class="line"><span class="language-javascript">          socket.<span class="title function_">emit</span>(<span class="string">&#x27;chat message&#x27;</span>, $(<span class="string">&#x27;#input&#x27;</span>).<span class="title function_">val</span>());</span></span><br><span class="line"><span class="language-javascript">          $(<span class="string">&#x27;#input&#x27;</span>).<span class="title function_">val</span>(<span class="string">&#x27;&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">          <span class="keyword">return</span> <span class="literal">false</span>;</span></span><br><span class="line"><span class="language-javascript">        &#125;);</span></span><br><span class="line"><span class="language-javascript">        socket.<span class="title function_">on</span>(<span class="string">&#x27;chat message&#x27;</span>, <span class="keyword">function</span>(<span class="params">msg</span>)&#123;</span></span><br><span class="line"><span class="language-javascript">          $(<span class="string">&#x27;#messages&#x27;</span>).<span class="title function_">append</span>($(<span class="string">&#x27;&lt;li&gt;&#x27;</span>).<span class="title function_">text</span>(msg));</span></span><br><span class="line"><span class="language-javascript">        &#125;);</span></span><br><span class="line"><span class="language-javascript">      &#125;);</span></span><br><span class="line"><span class="language-javascript">    </span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<ol>
<li>socket.io就是将webscoket内容进行了一个封装，相当于我们的express一样，这个不是唯一可以实现socket协议的包</li>
<li>服务器端和客户端都是使用on接收，使用emit发送</li>
</ol>
<h2 id="案例-你画我猜"><a href="#案例-你画我猜" class="headerlink" title="案例-你画我猜"></a>案例-你画我猜</h2><ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"><span class="keyword">var</span> http = <span class="built_in">require</span>(<span class="string">&#x27;http&#x27;</span>).<span class="title class_">Server</span>(app);</span><br><span class="line"><span class="keyword">var</span> io = <span class="built_in">require</span>(<span class="string">&#x27;socket.io&#x27;</span>)(http);</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">use</span>(express.<span class="title function_">static</span>(<span class="string">&quot;js&quot;</span>))</span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&#x27;/&#x27;</span>, <span class="keyword">function</span>(<span class="params">req, res</span>)&#123;</span><br><span class="line">  res.<span class="title function_">sendFile</span>(__dirname + <span class="string">&#x27;/index.html&#x27;</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">io.<span class="title function_">on</span>(<span class="string">&#x27;connection&#x27;</span>, <span class="keyword">function</span>(<span class="params">socket</span>)&#123;</span><br><span class="line">  socket.<span class="title function_">on</span>(<span class="string">&quot;straw&quot;</span>,<span class="keyword">function</span>(<span class="params">msg</span>)&#123;</span><br><span class="line">    <span class="comment">// 获取到消息立即广播出去</span></span><br><span class="line">    io.<span class="title function_">emit</span>(<span class="string">&quot;straw&quot;</span>,msg)</span><br><span class="line">  &#125;)</span><br><span class="line">  socket.<span class="title function_">on</span>(<span class="string">&quot;end&quot;</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="comment">// 获取到消息立即广播出去</span></span><br><span class="line">    io.<span class="title function_">emit</span>(<span class="string">&quot;end&quot;</span>)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">http.<span class="title function_">listen</span>(<span class="number">3000</span>, <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;listening on *:3000&#x27;</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<ol>
<li>index.html</li>
</ol>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">&quot;X-UA-Compatible&quot;</span> <span class="attr">content</span>=<span class="string">&quot;IE=edge&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">title</span>&gt;</span>你画我猜<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="language-css"></span></span><br><span class="line"><span class="language-css">    <span class="selector-tag">canvas</span>&#123;</span></span><br><span class="line"><span class="language-css">      <span class="attribute">cursor</span>: crosshair;</span></span><br><span class="line"><span class="language-css">    &#125;</span></span><br><span class="line"><span class="language-css">  </span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">canvas</span> <span class="attr">width</span>=<span class="string">&quot;800&quot;</span> <span class="attr">height</span>=<span class="string">&quot;400&quot;</span> <span class="attr">style</span>=<span class="string">&quot;border:1px solid #ccc&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">canvas</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&quot;/socket.io/socket.io.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">var</span> scoket = <span class="title function_">io</span>();</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">var</span> canvas = <span class="variable language_">document</span>.<span class="title function_">getElementsByTagName</span>(<span class="string">&quot;canvas&quot;</span>)[<span class="number">0</span>];</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">var</span> ctx = canvas.<span class="title function_">getContext</span>(<span class="string">&quot;2d&quot;</span>);</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="comment">// 主动发送</span></span></span><br><span class="line"><span class="language-javascript">    canvas.<span class="property">onmousedown</span> = <span class="keyword">function</span>(<span class="params">event</span>)&#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="keyword">var</span> x = event.<span class="property">offsetX</span>;</span></span><br><span class="line"><span class="language-javascript">      <span class="keyword">var</span> y = event.<span class="property">offsetY</span>;</span></span><br><span class="line"><span class="language-javascript">      ctx.<span class="title function_">beginPath</span>();</span></span><br><span class="line"><span class="language-javascript">      scoket.<span class="title function_">emit</span>(<span class="string">&quot;straw&quot;</span>,&#123;x,y&#125;)</span></span><br><span class="line"><span class="language-javascript">      canvas.<span class="property">onmousemove</span> = <span class="keyword">function</span>(<span class="params">event</span>)&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 从什么地方开始画</span></span></span><br><span class="line"><span class="language-javascript">        ctx.<span class="title function_">moveTo</span>(x,y);</span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 画到什么地方</span></span></span><br><span class="line"><span class="language-javascript">        ctx.<span class="title function_">lineTo</span>(event.<span class="property">offsetX</span>,event.<span class="property">offsetY</span>);</span></span><br><span class="line"><span class="language-javascript">        ctx.<span class="title function_">stroke</span>();</span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 通过多点成线</span></span></span><br><span class="line"><span class="language-javascript">        x = event.<span class="property">offsetX</span>;</span></span><br><span class="line"><span class="language-javascript">        y = event.<span class="property">offsetY</span>;</span></span><br><span class="line"><span class="language-javascript">        scoket.<span class="title function_">emit</span>(<span class="string">&quot;straw&quot;</span>,&#123;x,y&#125;)</span></span><br><span class="line"><span class="language-javascript">      &#125;</span></span><br><span class="line"><span class="language-javascript">      canvas.<span class="property">onmouseup</span> = <span class="keyword">function</span>(<span class="params">event</span>)&#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 结束绘画</span></span></span><br><span class="line"><span class="language-javascript">        x = <span class="literal">null</span>;</span></span><br><span class="line"><span class="language-javascript">        y = <span class="literal">null</span>;</span></span><br><span class="line"><span class="language-javascript">        canvas.<span class="property">onmousemove</span> = <span class="literal">null</span>;</span></span><br><span class="line"><span class="language-javascript">        scoket.<span class="title function_">emit</span>(<span class="string">&quot;end&quot;</span>);</span></span><br><span class="line"><span class="language-javascript">      &#125;</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">    <span class="comment">// 接收值并且渲染到画布上</span></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">var</span> x,y;</span></span><br><span class="line"><span class="language-javascript">    scoket.<span class="title function_">on</span>(<span class="string">&#x27;straw&#x27;</span>,<span class="keyword">function</span>(<span class="params">msg</span>)&#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="keyword">if</span>(!x || !y) &#123;</span></span><br><span class="line"><span class="language-javascript">        x = msg.<span class="property">x</span>;</span></span><br><span class="line"><span class="language-javascript">        y = msg.<span class="property">y</span>;</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">return</span>;</span></span><br><span class="line"><span class="language-javascript">      &#125;</span></span><br><span class="line"><span class="language-javascript">      ctx.<span class="title function_">beginPath</span>();</span></span><br><span class="line"><span class="language-javascript">      ctx.<span class="title function_">moveTo</span>(x,y);</span></span><br><span class="line"><span class="language-javascript">      ctx.<span class="title function_">lineTo</span>(msg.<span class="property">x</span> ,msg.<span class="property">y</span>);</span></span><br><span class="line"><span class="language-javascript">      ctx.<span class="title function_">stroke</span>();</span></span><br><span class="line"><span class="language-javascript">      y = msg.<span class="property">y</span>;</span></span><br><span class="line"><span class="language-javascript">      x = msg.<span class="property">x</span>;</span></span><br><span class="line"><span class="language-javascript">      <span class="variable language_">console</span>.<span class="title function_">log</span>(msg)</span></span><br><span class="line"><span class="language-javascript">    &#125;)</span></span><br><span class="line"><span class="language-javascript">    scoket.<span class="title function_">on</span>(<span class="string">&#x27;end&#x27;</span>,<span class="keyword">function</span>(<span class="params">msg</span>)&#123;</span></span><br><span class="line"><span class="language-javascript">      x = <span class="literal">null</span></span></span><br><span class="line"><span class="language-javascript">      y = <span class="literal">null</span>;</span></span><br><span class="line"><span class="language-javascript">    &#125;)</span></span><br><span class="line"><span class="language-javascript">  </span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h1 id="Koa框架"><a href="#Koa框架" class="headerlink" title="Koa框架"></a>Koa框架</h1><ol>
<li>NodeJS是一个异步的，官方的API支持的都是回调函数形式的编程模型，这样的设计会造成很多问题，比如回调的问题</li>
<li>Koa也是基于NodeJS平台封装的一个框架</li>
<li>我们之前学习了express，为什么还要学习Koa？</li>
<li>koa 是由 Express 原班人马打造的，致力于成为一个更小、更富有表现力、更健壮的 Web 框架。使用 koa 编写 web 应用，通过组合不同的 generator，可以免除重复繁琐的回调函数嵌套，并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件，它仅仅提供了一个轻量优雅的函数库，使得编写 Web 应用变得得心应手。</li>
<li>官网：<a target="_blank" rel="noopener" href="https://www.koajs.com.cn/">https://www.koajs.com.cn/</a></li>
</ol>
<h2 id="Koa的基本使用"><a href="#Koa的基本使用" class="headerlink" title="Koa的基本使用"></a>Koa的基本使用</h2><ol>
<li>命令</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install –save koa</span><br></pre></td></tr></table></figure>
<ol>
<li>创建app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 引入koa</span></span><br><span class="line"><span class="keyword">const</span> <span class="title class_">Koa</span> = <span class="built_in">require</span>(<span class="string">&#x27;koa&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> app = <span class="keyword">new</span> <span class="title class_">Koa</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 配置中间件</span></span><br><span class="line">app.<span class="title function_">use</span>(<span class="keyword">async</span> ctx =&gt; &#123;</span><br><span class="line">  ctx.<span class="property">body</span> = <span class="string">&#x27;Hello World&#x27;</span>;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 监听端口</span></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>);</span><br></pre></td></tr></table></figure>
<h2 id="Koa的前置知识-关于ES6"><a href="#Koa的前置知识-关于ES6" class="headerlink" title="Koa的前置知识-关于ES6"></a>Koa的前置知识-关于ES6</h2><h3 id="let和const"><a href="#let和const" class="headerlink" title="let和const"></a>let和const</h3><ol>
<li>我们之前学习JavaScript的时候声明一个变量的时候使用的是var，我们接下来学习两个let和const</li>
<li>var是有变量声明提升的，let和const是没有的。let和const是有块级作用域的，var没有。let和const的区别是一个变量，一个是常量</li>
<li>关于变量声明提升</li>
<li>关于变量声明提升</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br><span class="line"><span class="keyword">var</span> a = <span class="number">100</span>;</span><br></pre></td></tr></table></figure>
<ol>
<li>let和const</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br><span class="line"><span class="keyword">let</span> a = <span class="number">100</span>;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br><span class="line"><span class="keyword">const</span> a = <span class="number">100</span>;</span><br></pre></td></tr></table></figure>
<ol>
<li>关于块级作用域</li>
<li>var的定义</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(<span class="literal">true</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> a = <span class="number">100</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br></pre></td></tr></table></figure>
<ol>
<li>let好const</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(<span class="literal">true</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> a = <span class="number">100</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(<span class="literal">true</span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> a = <span class="number">100</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br></pre></td></tr></table></figure>
<ol>
<li>关于let和const的主要区别</li>
<li>声明是变量，let定义的值是可以被修改，const定义的值只能使用不能修改</li>
<li>let：变量</li>
<li>const：常量</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a = <span class="number">100</span>;</span><br><span class="line">a = a + <span class="number">5</span>;</span><br><span class="line"><span class="keyword">let</span> b = <span class="number">100</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a + b)</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> a = <span class="number">100</span>;</span><br><span class="line">a = a + <span class="number">5</span>;</span><br><span class="line"><span class="keyword">const</span> b = <span class="number">100</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a + b)</span><br></pre></td></tr></table></figure>
<h3 id="箭头函数"><a href="#箭头函数" class="headerlink" title="箭头函数"></a>箭头函数</h3><ol>
<li>我们看普通定义一个函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  a : <span class="keyword">function</span>(<span class="params">num</span>)&#123;</span><br><span class="line">    <span class="keyword">return</span> num</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>使用箭头函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  a : <span class="function">(<span class="params">num</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> num</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>还可以这样定义</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  a : <span class="function"><span class="params">num</span>=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> num</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>甚至还可以这样定义</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  a : <span class="function"><span class="params">num</span> =&gt;</span> num</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="async和await"><a href="#async和await" class="headerlink" title="async和await"></a>async和await</h3><ol>
<li>我们工作中常会遇到异步调用的函数，我们的koa和express封装的中间件都是异步的</li>
<li>async就是异步的意思，我们定义一个函数可以使用async来表示这个函数是一个异步函数</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">timeOut</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">&quot;异步函数&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">timeOut</span>())</span><br></pre></td></tr></table></figure>
<ol>
<li>你会发现输出结果是一个Promise对象</li>
<li>此时我们如何使用这个异步的定义函数，必须用await（等待），需要注意的是await必须在async中使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">timeOut</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">&quot;异步函数&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">result</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> r1 = <span class="keyword">await</span> <span class="title function_">timeOut</span>();</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(r1)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="Promise对象"><a href="#Promise对象" class="headerlink" title="Promise对象"></a>Promise对象</h3><ol>
<li>Promise对象也是ES6的新语法，它主要是用来解决异步的回调黑洞</li>
<li>我们看一个简单的Promise的封装</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">testPromise</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve</span>)=&gt;</span>&#123;</span><br><span class="line">    <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="title function_">resolve</span>(<span class="string">&quot;value&quot;</span>)</span><br><span class="line">    &#125;, <span class="number">2000</span>);</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">result</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="comment">// 接收Promise的值</span></span><br><span class="line">  <span class="keyword">const</span> v = <span class="keyword">await</span> <span class="title function_">testPromise</span>()</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(v)</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">result</span>()</span><br></pre></td></tr></table></figure>
<h2 id="Koa的路由"><a href="#Koa的路由" class="headerlink" title="Koa的路由"></a>Koa的路由</h2><ol>
<li>Koa的路由和express不同，express里面包含了路由的中间件，但是koa则没有，需要自己配置</li>
<li>npm地址：<a target="_blank" rel="noopener" href="https://github.com/koajs/router/blob/HEAD/API.md">https://github.com/koajs/router/blob/HEAD/API.md</a></li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install –-save koa koa-router</span><br></pre></td></tr></table></figure>
<ol>
<li>app.js</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title class_">Koa</span> = <span class="built_in">require</span>(<span class="string">&#x27;koa&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> <span class="title class_">Router</span> = <span class="built_in">require</span>(<span class="string">&#x27;koa-router&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> app = <span class="keyword">new</span> <span class="title class_">Koa</span>();</span><br><span class="line"><span class="keyword">const</span> router = <span class="keyword">new</span> <span class="title class_">Router</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 路由中间件</span></span><br><span class="line">router.<span class="title function_">get</span>(<span class="string">&#x27;/&#x27;</span>, <span class="function">(<span class="params">ctx, next</span>) =&gt;</span> &#123;</span><br><span class="line">  ctx.<span class="property">body</span> = <span class="string">&quot;马士兵教育&quot;</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">app</span><br><span class="line">  .<span class="title function_">use</span>(router.<span class="title function_">routes</span>()) <span class="comment">//启动路由</span></span><br><span class="line">  .<span class="title function_">use</span>(router.<span class="title function_">allowedMethods</span>()); <span class="comment">//官方推荐使用，主要作用是根据ctx.status设置response的响应头</span></span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;监听3000&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="Koa-router的get请求"><a href="#Koa-router的get请求" class="headerlink" title="Koa-router的get请求"></a>Koa-router的get请求</h2><ol>
<li>koa中的ctx集成了所有可用的相关url的信息</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">router.<span class="title function_">get</span>(<span class="string">&#x27;/yy&#x27;</span>, <span class="function">(<span class="params">ctx, next</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(ctx)</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<ol>
<li>常用的参数request.querystring和request的query，一共两种方式返回，一种字符串一种转换为对象</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">router.<span class="title function_">get</span>(<span class="string">&#x27;/yy&#x27;</span>, <span class="function">(<span class="params">ctx, next</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="comment">// 获取URL</span></span><br><span class="line">  <span class="keyword">let</span> url= ctx.<span class="property">url</span>;</span><br><span class="line">  <span class="comment">// 从request中获取GET请求参数</span></span><br><span class="line">  <span class="keyword">let</span> request = ctx.<span class="property">request</span>;</span><br><span class="line">  <span class="keyword">let</span> queryObj = request.<span class="property">query</span></span><br><span class="line"></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(request.<span class="property">querystring</span>)</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(request.<span class="property">query</span>)</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<ol>
<li>koa和express一样也可以设置动态路由</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">router.<span class="title function_">get</span>(<span class="string">&quot;/class/:name&quot;</span>,<span class="function">(<span class="params">ctx</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(ctx.<span class="property">params</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>需要注意的是，完全匹配的问题，比如下面的</li>
<li>由于我们设置动态路由的时候只设置了一级，所以，此时会遇到捕获不到的请情况，如果想匹配任何可以使用通配(.*)</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">router.<span class="title function_">get</span>(<span class="string">&quot;/class/:name/(.*)&quot;</span>,<span class="function">(<span class="params">ctx</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(ctx.<span class="property">params</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>如果使用通配，则后面就不应该由其他的动态捕获，因为*会抓取所有</li>
</ol>
<h2 id="Koa使用ejs模板引擎"><a href="#Koa使用ejs模板引擎" class="headerlink" title="Koa使用ejs模板引擎"></a>Koa使用ejs模板引擎</h2><ol>
<li>依赖</li>
<li>和express一样，建议使用ejs模板引擎，和路由一样，也需要配置模板引擎的相关依赖</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install –save ejs koa-views</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title class_">Koa</span> = <span class="built_in">require</span>(<span class="string">&#x27;koa&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> <span class="title class_">Router</span> = <span class="built_in">require</span>(<span class="string">&#x27;koa-router&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> views = <span class="built_in">require</span>(<span class="string">&quot;koa-views&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> app = <span class="keyword">new</span> <span class="title class_">Koa</span>();</span><br><span class="line"><span class="keyword">const</span> router = <span class="keyword">new</span> <span class="title class_">Router</span>();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 动态路由，需要注意的是我们的模板引擎的渲染是异步的，所以必须使用async和await去配合使用</span></span><br><span class="line">router.<span class="title function_">get</span>(<span class="string">&quot;/class/:name/(.*)&quot;</span>,<span class="keyword">async</span> (ctx)=&gt;&#123;</span><br><span class="line">	<span class="comment">//渲染模板引擎为index.ejs</span></span><br><span class="line">  <span class="keyword">await</span> ctx.<span class="title function_">render</span>(<span class="string">&quot;index&quot;</span>)</span><br><span class="line"></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用模板引擎，views方法是koa-router提供的，内部的第一个参数指的是模板引擎的文件夹</span></span><br><span class="line">app.<span class="title function_">use</span>(<span class="title function_">views</span>(<span class="string">&quot;views&quot;</span>,&#123;</span><br><span class="line">  <span class="attr">extension</span>: <span class="string">&quot;ejs&quot;</span> <span class="comment">//模板引擎拓展名</span></span><br><span class="line">&#125;))</span><br><span class="line"></span><br><span class="line">app</span><br><span class="line">  .<span class="title function_">use</span>(router.<span class="title function_">routes</span>()) <span class="comment">//启动路由</span></span><br><span class="line">  .<span class="title function_">use</span>(router.<span class="title function_">allowedMethods</span>()); <span class="comment">//官方推荐使用，主要作用是根据ctx.status设置response的响应头</span></span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;监听3000&quot;</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<ol>
<li>views文件夹内部的index.ejs</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;!<span class="variable constant_">DOCTYPE</span> html&gt;</span><br><span class="line">&lt;html lang=&quot;en&quot;&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">  &lt;meta charset=&quot;UTF-8&quot;&gt;</span><br><span class="line">  &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;</span><br><span class="line">  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;</span><br><span class="line">  &lt;title&gt;Document&lt;/title&gt;</span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">  &lt;h1&gt;我是模板引擎&lt;/h1&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<h2 id="Koa-router的post请求"><a href="#Koa-router的post请求" class="headerlink" title="Koa-router的post请求"></a>Koa-router的post请求</h2><ol>
<li>post请求在获取参数的时候仅仅依靠koa-router是不行的，还需要安装koa-bodyparser，来获取post请求的参数</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install –save koa-bodyparser</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">use</span>(<span class="title function_">bodyparser</span>())</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">router.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="keyword">async</span> (ctx)=&gt;&#123;</span><br><span class="line">  <span class="keyword">await</span> ctx.<span class="title function_">render</span>(<span class="string">&quot;index&quot;</span>)</span><br><span class="line">&#125;)</span><br><span class="line">router.<span class="title function_">post</span>(<span class="string">&quot;/addForm&quot;</span>,<span class="function">(<span class="params">ctx</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(ctx.<span class="property">request</span>.<span class="property">body</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="文件静态化"><a href="#文件静态化" class="headerlink" title="文件静态化"></a>文件静态化</h2><ol>
<li>koa中使用的是koa-static来静态文件资源</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cnpm install –-save koa-static</span><br></pre></td></tr></table></figure>
<ol>
<li>使用</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">use</span>(<span class="title function_">static</span>(__dirname+<span class="string">&quot;/assets&quot;</span>))</span><br></pre></td></tr></table></figure>
<ol>
<li>此时assets文件夹整体呗静态化，内部的文件就自动拥有了路由</li>
</ol>
<h1 id="NodeJS的跨域-CORS"><a href="#NodeJS的跨域-CORS" class="headerlink" title="NodeJS的跨域-CORS"></a>NodeJS的跨域-CORS</h1><ol>
<li>CORS是一个W3C标准，全称是”跨域资源共享”（Cross-origin resource sharing）。</li>
<li>它允许浏览器向跨源服务器，发出XMLHttpRequest请求，从而克服了AJAX只能同源使用的限制。</li>
<li>CORS需要浏览器和服务器同时支持。目前，所有浏览器都支持该功能，IE浏览器不能低于IE10。</li>
<li>整个CORS通信过程，都是浏览器自动完成，不需要用户参与。对于开发者来说，CORS通信与同源的AJAX通信没有差别，代码完全一样。浏览器一旦发现AJAX请求跨源，就会自动添加一些附加的头信息，有时还会多出一次附加的请求，但用户不会有感觉。</li>
<li>因此，实现CORS通信的关键是服务器。只要服务器实现了CORS接口，就可以跨源通信。</li>
<li>在前面的课程中我们讲过了关于跨域的知识，跨域指的是不同源相互请求，传递信息或数据</li>
<li>我们可以利用NodeJS实现CORS跨域</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&quot;express&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/&quot;</span>,<span class="function">(<span class="params">req,res</span>)=&gt;</span>&#123;</span><br><span class="line">  <span class="comment">//配置请求的域名，*代表任意</span></span><br><span class="line">  res.<span class="title function_">header</span>(<span class="string">&quot;Access-Control-Allow-Origin&quot;</span>, <span class="string">&quot;*&quot;</span>);</span><br><span class="line">  <span class="comment">// 支持跨域请求类型</span></span><br><span class="line">  res.<span class="title function_">header</span>(<span class="string">&quot;Access-Control-Allow-Methods&quot;</span>,<span class="string">&quot;PUT,POST,GET,DELETE,OPTIONS&quot;</span>);</span><br><span class="line">  <span class="comment">//配置请求头信息，包含字符集等等</span></span><br><span class="line">  res.<span class="title function_">header</span>(<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;application/json;charset=utf-8&quot;</span>);</span><br><span class="line">  res.<span class="title function_">json</span>(&#123;</span><br><span class="line">    <span class="attr">a</span>:<span class="number">100</span></span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3000</span>,<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">3000</span>)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="http://example.com">晚夜微雨问海棠</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="http://example.com/posts/3a5743c3.html">http://example.com/posts/3a5743c3.html</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="http://example.com" target="_blank">晚夜微雨问海棠のBlog</a>！</span></div></div><div class="tag_share"><div class="post_share"><div class="social-share" data-image="https://s1.ax1x.com/2022/12/03/zrV6Q1.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://s1.ax1x.com/2022/11/15/zE9P7d.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/15/zE9P7d.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="https://s1.ax1x.com/2022/11/15/zE9ung.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/15/zE9ung.jpg" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/posts/954c8db1.html" title="Google_V8原理"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2023/06/14/pCn45LT.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-06-14</div><div class="title">Google_V8原理</div></div></a></div><div><a href="/posts/f418d067.html" title="H5基础"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNllfe.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-10-06</div><div class="title">H5基础</div></div></a></div><div><a href="/posts/3da79d5b.html" title="JavaScript入门"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2022/12/08/z2ar8O.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-10-21</div><div class="title">JavaScript入门</div></div></a></div><div><a href="/posts/f818a4a.html" title="JavaScript面向对象"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/06/xXrY34.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-11-06</div><div class="title">JavaScript面向对象</div></div></a></div><div><a href="/posts/50839dad.html" title="ECMAScript基础"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/09/zS8LRA.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-11-09</div><div class="title">ECMAScript基础</div></div></a></div><div><a href="/posts/c02b1e8e.html" title="PHP服务器&#x2F;Ajax"><img class="cover" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/17/zmFYzd.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-11-17</div><div class="title">PHP服务器&#x2F;Ajax</div></div></a></div></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div class="vcomment" id="vcomment"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content is-expand"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Node-js"><span class="toc-number">1.</span> <span class="toc-text">Node.js</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Node-js%E7%9A%84%E7%AE%80%E4%BB%8B%E5%92%8C%E5%AE%89%E8%A3%85"><span class="toc-number">1.1.</span> <span class="toc-text">Node.js的简介和安装</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Node-js%E7%9A%84%E7%AE%80%E4%BB%8B"><span class="toc-number">1.1.1.</span> <span class="toc-text">Node.js的简介</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Node-js-%E7%9A%84%E6%9D%A5%E5%8E%86"><span class="toc-number">1.1.2.</span> <span class="toc-text">Node.js 的来历</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%89%E8%A3%85Node-js"><span class="toc-number">1.1.3.</span> <span class="toc-text">安装Node.js</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%B3%E4%BA%8ECMD%E5%91%BD%E4%BB%A4"><span class="toc-number">1.2.</span> <span class="toc-text">关于CMD命令</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%9A%84%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F"><span class="toc-number">1.3.</span> <span class="toc-text">计算机的环境变量</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Node-js%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95"><span class="toc-number">1.4.</span> <span class="toc-text">Node.js的使用方法</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#js%E7%9A%84%E5%AE%BF%E4%B8%BB%E7%8E%AF%E5%A2%83"><span class="toc-number">1.4.1.</span> <span class="toc-text">js的宿主环境</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8E%E6%96%87%E4%BB%B6%E7%9B%AE%E5%BD%95%E4%BD%8D%E7%BD%AE"><span class="toc-number">1.4.2.</span> <span class="toc-text">关于文件目录位置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Node-js%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">1.4.3.</span> <span class="toc-text">Node.js的基本使用</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8Node-js%E6%90%AD%E5%BB%BA%E6%9C%8D%E5%8A%A1%E5%99%A8"><span class="toc-number">1.5.</span> <span class="toc-text">使用Node.js搭建服务器</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B3%E4%BA%8Edemo%E7%9A%84%E6%90%AD%E5%BB%BA"><span class="toc-number">1.5.1.</span> <span class="toc-text">关于demo的搭建</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#res-end"><span class="toc-number">1.5.2.</span> <span class="toc-text">res.end()</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#res-write"><span class="toc-number">1.5.3.</span> <span class="toc-text">res.write()</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Node-js%E7%9A%84%E5%86%85%E7%BD%AE%E5%8A%9F%E8%83%BD"><span class="toc-number">1.6.</span> <span class="toc-text">Node.js的内置功能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#fs%E6%A8%A1%E5%9D%97"><span class="toc-number">1.6.1.</span> <span class="toc-text">fs模块</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%B7%AF%E7%94%B1%EF%BC%88%E2%98%85%EF%BC%89"><span class="toc-number">1.6.2.</span> <span class="toc-text">路由（★）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%A8%A1%E4%BB%BF%E7%9F%A5%E4%B9%8E%E8%B7%AF%E7%94%B1%E7%9A%84%E9%A1%B6%E5%B1%82%E8%AE%BE%E8%AE%A1"><span class="toc-number">1.6.3.</span> <span class="toc-text">模仿知乎路由的顶层设计</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%A1%B6%E5%B1%82%E8%B7%AF%E7%94%B1%E8%AE%BE%E8%AE%A1%E4%BC%9A%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98"><span class="toc-number">1.6.4.</span> <span class="toc-text">顶层路由设计会遇到的问题</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%A8%A1%E5%9D%97%EF%BC%88%E2%98%85%EF%BC%89"><span class="toc-number">1.7.</span> <span class="toc-text">模块（★）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#HTML%E7%9A%84%E5%A4%9A%E6%96%87%E4%BB%B6%E5%BC%95%E7%94%A8"><span class="toc-number">1.7.1.</span> <span class="toc-text">HTML的多文件引用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Node-js%E7%9A%84%E5%A4%9A%E6%96%87%E4%BB%B6%E5%BC%95%E7%94%A8"><span class="toc-number">1.7.2.</span> <span class="toc-text">Node.js的多文件引用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Node-js%E4%B8%AD%E7%9A%84js%E6%96%87%E4%BB%B6%E4%BD%9C%E7%94%A8%E5%9F%9F%E5%A4%A9%E7%94%9F%E9%9A%94%E7%A6%BB"><span class="toc-number">1.7.3.</span> <span class="toc-text">Node.js中的js文件作用域天生隔离</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#exports%E5%91%BD%E4%BB%A4"><span class="toc-number">1.7.4.</span> <span class="toc-text">exports命令</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#exports%E7%9A%84%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4"><span class="toc-number">1.7.5.</span> <span class="toc-text">exports的命名空间</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#module-exports%E5%91%BD%E4%BB%A4"><span class="toc-number">1.7.6.</span> <span class="toc-text">module.exports命令</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%96%87%E4%BB%B6%E5%A4%B9%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-number">1.7.7.</span> <span class="toc-text">文件夹的使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#node-modules%E6%96%87%E4%BB%B6%E5%A4%B9"><span class="toc-number">1.7.8.</span> <span class="toc-text">node_modules文件夹</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#npm%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8-%E2%98%85"><span class="toc-number">1.8.</span> <span class="toc-text">npm的基本使用(★)</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#npm%E7%9A%84%E5%AE%89%E8%A3%85"><span class="toc-number">1.8.1.</span> <span class="toc-text">npm的安装</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B0%8F%E6%A1%88%E4%BE%8B%EF%BC%9A%E6%97%A5%E6%9C%9F%E8%BD%AC%E6%8D%A2"><span class="toc-number">1.8.2.</span> <span class="toc-text">小案例：日期转换</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#npm%E7%9A%84%E8%BA%AB%E4%BB%BD%E8%AF%81%E5%92%8C%E4%BE%9D%E8%B5%96"><span class="toc-number">1.8.3.</span> <span class="toc-text">npm的身份证和依赖</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B7%98%E5%AE%9D%E9%95%9C%E5%83%8F"><span class="toc-number">1.9.</span> <span class="toc-text">淘宝镜像</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Express%E6%A1%86%E6%9E%B6"><span class="toc-number">1.10.</span> <span class="toc-text">Express框架</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">1.10.1.</span> <span class="toc-text">基本使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%AD%E9%97%B4%E4%BB%B6"><span class="toc-number">1.10.2.</span> <span class="toc-text">中间件</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E4%B8%AD%E9%97%B4%E4%BB%B6"><span class="toc-number">1.10.2.1.</span> <span class="toc-text">什么是中间件</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%B8%AD%E9%97%B4%E4%BB%B6%E7%9A%84%E8%B7%AF%E5%BE%84"><span class="toc-number">1.10.2.2.</span> <span class="toc-text">中间件的路径</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%B8%AD%E9%97%B4%E4%BB%B6%E7%9A%84%E9%80%9A%E9%85%8D%E7%AC%A6"><span class="toc-number">1.10.2.3.</span> <span class="toc-text">中间件的通配符</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%B8%AD%E9%97%B4%E4%BB%B6%E7%9A%84%E9%A1%BA%E5%BA%8F"><span class="toc-number">1.10.2.4.</span> <span class="toc-text">中间件的顺序</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#next-%E6%96%B9%E6%B3%95"><span class="toc-number">1.10.2.5.</span> <span class="toc-text">next()方法</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%BE%93%E5%87%BA"><span class="toc-number">1.10.3.</span> <span class="toc-text">输出</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%96%87%E4%BB%B6%E5%A4%B9%E7%9A%84%E9%9D%99%E6%80%81%E5%8C%96"><span class="toc-number">1.10.4.</span> <span class="toc-text">文件夹的静态化</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Express%E7%9A%84%E8%AF%B7%E6%B1%82"><span class="toc-number">1.11.</span> <span class="toc-text">Express的请求</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#GET%E8%AF%B7%E6%B1%82"><span class="toc-number">1.11.1.</span> <span class="toc-text">GET请求</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#POST%E8%AF%B7%E6%B1%82"><span class="toc-number">1.11.2.</span> <span class="toc-text">POST请求</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B6%E4%BB%96%E6%96%B9%E5%BC%8F%E7%9A%84%E8%AF%B7%E6%B1%82"><span class="toc-number">1.11.3.</span> <span class="toc-text">其他方式的请求</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#RESTful%E9%A3%8E%E6%A0%BC%E7%9A%84%E8%B7%AF%E7%94%B1"><span class="toc-number">1.12.</span> <span class="toc-text">RESTful风格的路由</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#RESTful%E9%A3%8E%E6%A0%BC%E7%9A%84TodoList"><span class="toc-number">1.13.</span> <span class="toc-text">RESTful风格的TodoList</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MVC%E6%9E%B6%E6%9E%84%E7%9A%84%E4%BB%8B%E7%BB%8D"><span class="toc-number">1.14.</span> <span class="toc-text">MVC架构的介绍</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#MongoDB"><span class="toc-number">2.</span> <span class="toc-text">MongoDB</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#NoSQL%E7%9A%84%E7%AE%80%E4%BB%8B"><span class="toc-number">2.1.</span> <span class="toc-text">NoSQL的简介</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MongoDB%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%B8%8B%E8%BD%BD%E5%92%8C%E5%AE%89%E8%A3%85"><span class="toc-number">2.2.</span> <span class="toc-text">MongoDB数据库的下载和安装</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AF%B9%E4%BA%8EMogo%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E7%AE%80%E5%8D%95%E6%93%8D%E4%BD%9C"><span class="toc-number">2.3.</span> <span class="toc-text">对于Mogo数据库的简单操作</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8mongobooster%E5%8F%AF%E8%A7%86%E5%8C%96%E7%AE%A1%E7%90%86%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BD%AF%E4%BB%B6"><span class="toc-number">2.4.</span> <span class="toc-text">使用mongobooster可视化管理数据库软件</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Node-js%E6%93%8D%E4%BD%9CMongoDB"><span class="toc-number">3.</span> <span class="toc-text">Node.js操作MongoDB</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%BF%9E%E6%8E%A5%E6%95%B0%E6%8D%AE%E5%BA%93"><span class="toc-number">3.1.</span> <span class="toc-text">连接数据库</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9F%A5%E8%AF%A2%E5%92%8C%E6%8F%92%E5%85%A5%E5%91%BD%E4%BB%A4"><span class="toc-number">3.2.</span> <span class="toc-text">查询和插入命令</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Mongoose-%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-number">4.</span> <span class="toc-text">Mongoose 的使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8-1"><span class="toc-number">4.1.</span> <span class="toc-text">基本使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C-%E5%A2%9E%E5%8A%A0"><span class="toc-number">4.2.</span> <span class="toc-text">基本操作-增加</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C-%E5%88%A0%E9%99%A4"><span class="toc-number">4.3.</span> <span class="toc-text">基本操作-删除</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C-%E4%BF%AE%E6%94%B9"><span class="toc-number">4.4.</span> <span class="toc-text">基本操作-修改</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C-%E6%9F%A5%E8%AF%A2"><span class="toc-number">4.5.</span> <span class="toc-text">基本操作-查询</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Echarts"><span class="toc-number">5.</span> <span class="toc-text">Echarts</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Echarts%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">5.1.</span> <span class="toc-text">Echarts的基本使用</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%B0%8F%E5%B0%8F%E8%B0%83%E6%9F%A5%E8%A1%A8%E5%8D%95"><span class="toc-number">6.</span> <span class="toc-text">小小调查表单</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A1%A8%E5%8D%95%E6%8F%90%E4%BA%A4%E9%A1%B5%E9%9D%A2"><span class="toc-number">6.1.</span> <span class="toc-text">表单提交页面</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#app-js%E8%B7%AF%E7%94%B1%E8%AE%BE%E8%AE%A1"><span class="toc-number">6.2.</span> <span class="toc-text">app.js路由设计</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BB%9F%E8%AE%A1%E5%9B%BE%E8%A1%A8%E9%A1%B5%E9%9D%A2"><span class="toc-number">6.3.</span> <span class="toc-text">统计图表页面</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%A8%A1%E6%9D%BF%E5%BC%95%E6%93%8E"><span class="toc-number">7.</span> <span class="toc-text">模板引擎</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#cookie%E5%92%8Csession"><span class="toc-number">8.</span> <span class="toc-text">cookie和session</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#cookie"><span class="toc-number">8.1.</span> <span class="toc-text">cookie</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#session"><span class="toc-number">8.2.</span> <span class="toc-text">session</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%88%B6%E4%BD%9C%E7%99%BB%E5%BD%95%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2"><span class="toc-number">9.</span> <span class="toc-text">制作登录注册页面</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E7%9A%84%E6%96%87%E4%BB%B6%E5%A4%B9%E7%BB%93%E6%9E%84"><span class="toc-number">9.1.</span> <span class="toc-text">基本的文件夹结构</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%A1%88%E4%BE%8B%E4%BD%9C%E4%B8%9A"><span class="toc-number">9.2.</span> <span class="toc-text">案例作业</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#socket"><span class="toc-number">10.</span> <span class="toc-text">socket</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#socket%E5%8D%8F%E8%AE%AE%E5%AE%9E%E7%8E%B0%E8%81%8A%E5%A4%A9%E5%AE%A4"><span class="toc-number">10.1.</span> <span class="toc-text">socket协议实现聊天室</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%A1%88%E4%BE%8B-%E4%BD%A0%E7%94%BB%E6%88%91%E7%8C%9C"><span class="toc-number">10.2.</span> <span class="toc-text">案例-你画我猜</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Koa%E6%A1%86%E6%9E%B6"><span class="toc-number">11.</span> <span class="toc-text">Koa框架</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Koa%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">11.1.</span> <span class="toc-text">Koa的基本使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Koa%E7%9A%84%E5%89%8D%E7%BD%AE%E7%9F%A5%E8%AF%86-%E5%85%B3%E4%BA%8EES6"><span class="toc-number">11.2.</span> <span class="toc-text">Koa的前置知识-关于ES6</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#let%E5%92%8Cconst"><span class="toc-number">11.2.1.</span> <span class="toc-text">let和const</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0"><span class="toc-number">11.2.2.</span> <span class="toc-text">箭头函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#async%E5%92%8Cawait"><span class="toc-number">11.2.3.</span> <span class="toc-text">async和await</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise%E5%AF%B9%E8%B1%A1"><span class="toc-number">11.2.4.</span> <span class="toc-text">Promise对象</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Koa%E7%9A%84%E8%B7%AF%E7%94%B1"><span class="toc-number">11.3.</span> <span class="toc-text">Koa的路由</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Koa-router%E7%9A%84get%E8%AF%B7%E6%B1%82"><span class="toc-number">11.4.</span> <span class="toc-text">Koa-router的get请求</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Koa%E4%BD%BF%E7%94%A8ejs%E6%A8%A1%E6%9D%BF%E5%BC%95%E6%93%8E"><span class="toc-number">11.5.</span> <span class="toc-text">Koa使用ejs模板引擎</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Koa-router%E7%9A%84post%E8%AF%B7%E6%B1%82"><span class="toc-number">11.6.</span> <span class="toc-text">Koa-router的post请求</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%96%87%E4%BB%B6%E9%9D%99%E6%80%81%E5%8C%96"><span class="toc-number">11.7.</span> <span class="toc-text">文件静态化</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#NodeJS%E7%9A%84%E8%B7%A8%E5%9F%9F-CORS"><span class="toc-number">12.</span> <span class="toc-text">NodeJS的跨域-CORS</span></a></li></ol></div></div></div></div></main><footer id="footer" style="background-image: url('https://s1.ax1x.com/2022/12/03/zrV6Q1.jpg')"><div id="footer-wrap"><div class="copyright">&copy;2022 - 2023 By 晚夜微雨问海棠</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="chat_btn" type="button" title="聊天"><i class="fas fa-sms"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div id="rightMenu"><div class="rightMenu-group rightMenu-small"><div class="rightMenu-item" id="menu-backward"><i class="fa-solid fa-arrow-left"></i></div><div class="rightMenu-item" id="menu-forward"><i class="fa-solid fa-arrow-right"></i></div><div class="rightMenu-item" id="menu-refresh"><i class="fa-solid fa-arrow-rotate-right"></i></div><div class="rightMenu-item" id="menu-home"><i class="fa-solid fa-house"></i></div></div><div class="rightMenu-group rightMenu-line rightMenuOther"><a class="rightMenu-item menu-link" href="/archives/"><i class="fa-solid fa-archive"></i><span>文章归档</span></a><a class="rightMenu-item menu-link" href="/categories/"><i class="fa-solid fa-folder-open"></i><span>文章分类</span></a><a class="rightMenu-item menu-link" href="/tags/"><i class="fa-solid fa-tags"></i><span>文章标签</span></a></div><div class="rightMenu-group rightMenu-line rightMenuNormal"><div class="rightMenu-item" id="menu-translate"><i class="fa-solid fa-earth-asia"></i><span>繁简切换</span></div><div class="rightMenu-item" id="menu-darkmode"><i class="fa-solid fa-moon"></i><span>切换模式</span></div></div></div><div id="rightmenu-mask"></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/js/search/local-search.js"></script><script>var preloader = {
  endLoading: () => {
    document.body.style.overflow = 'auto';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.remove("loaded")

  }
}
window.addEventListener('load',preloader.endLoading())</script><div class="js-pjax"><script>(() => {
  const $mermaidWrap = document.querySelectorAll('#article-container .mermaid-wrap')
  if ($mermaidWrap.length) {
    window.runMermaid = () => {
      window.loadMermaid = true
      const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'default'

      Array.from($mermaidWrap).forEach((item, index) => {
        const mermaidSrc = item.firstElementChild
        const mermaidThemeConfig = '%%{init:{ \'theme\':\'' + theme + '\'}}%%\n'
        const mermaidID = 'mermaid-' + index
        const mermaidDefinition = mermaidThemeConfig + mermaidSrc.textContent
        mermaid.mermaidAPI.render(mermaidID, mermaidDefinition, (svgCode) => {
          mermaidSrc.insertAdjacentHTML('afterend', svgCode)
        })
      })
    }

    const loadMermaid = () => {
      window.loadMermaid ? runMermaid() : getScript('https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js').then(runMermaid)
    }

    window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid)
  }
})()</script><script>function loadValine () {
  function initValine () {
    const valine = new Valine(Object.assign({
      el: '#vcomment',
      appId: '',
      appKey: '',
      avatar: 'monsterid',
      serverURLs: '',
      emojiMaps: "",
      path: window.location.pathname,
      visitor: false
    }, null))
  }

  if (typeof Valine === 'function') initValine() 
  else getScript('https://cdn.jsdelivr.net/npm/valine/dist/Valine.min.js').then(initValine)
}

if ('Valine' === 'Valine' || !true) {
  if (true) btf.loadComment(document.getElementById('vcomment'),loadValine)
  else setTimeout(loadValine, 0)
} else {
  function loadOtherComment () {
    loadValine()
  }
}</script></div><div class="aplayer no-destroy" data-id="7625372994" data-server="netease" data-type="playlist" data-fixed="true" data-autoplay="true"> </div> <script defer src="https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js"></script> <script src="/swiper/swiper.min.js"></script> <script src="/swiper/swiperindex.js"></script> <script src="//cdn.bootcss.com/pace/1.0.2/pace.min.js"></script> <script src="/js/title.js"></script> <script defer data-pjax src="/js/cat.js"></script> <script defer data-pjax src="/js/rightMenu.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = false;
POWERMODE.mobile = false;
document.body.addEventListener('input', POWERMODE);
</script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/click-heart.min.js" async="async" mobile="false"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/metingjs/dist/Meting.min.js"></script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show","#web_bg",".js-pjax"]

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:send', function () {

  // removeEventListener scroll 
  window.tocScrollFn && window.removeEventListener('scroll', window.tocScrollFn)
  window.scrollCollect && window.removeEventListener('scroll', scrollCollect)

  typeof preloader === 'object' && preloader.initLoading()
  document.getElementById('rightside').style.cssText = "opacity: ''; transform: ''"
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  //reset readmode
  const $bodyClassList = document.body.classList
  $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')

  typeof disqusjs === 'object' && disqusjs.destroy()
})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  document.querySelectorAll('script[data-pjax]').forEach(item => {
    const newScript = document.createElement('script')
    const content = item.text || item.textContent || item.innerHTML || ""
    Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    newScript.appendChild(document.createTextNode(content))
    item.parentNode.replaceChild(newScript, item)
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof chatBtnFn === 'function' && chatBtnFn()
  typeof panguInit === 'function' && panguInit()

  // google analytics
  typeof gtag === 'function' && gtag('config', '', {'page_path': window.location.pathname});

  // baidu analytics
  typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()

  typeof preloader === 'object' && preloader.endLoading()
})

document.addEventListener('pjax:error', (e) => {
  if (e.request.status === 404) {
    pjax.loadUrl('/404.html')
  }
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><!-- hexo injector body_end start --><script data-pjax>function history_calendar_injector_config(){
                var parent_div_git = document.getElementsByClassName('sticky_layout')[0];
                var item_html = '<div class="card-widget card-history"><div class="card-content"><div class="item-headline"><i class="fas fa-clock fa-spin"></i><span>那年今日</span></div><div id="history-baidu" style="height: 100px;overflow: hidden"><div class="history_swiper-container" id="history-container" style="width: 100%;height: 100%"><div class="swiper-wrapper" id="history_container_wrapper" style="height:20px"></div></div></div></div>';
                console.log('已挂载history_calendar')
                // parent_div_git.innerHTML=item_html+parent_div_git.innerHTML // 无报错，但不影响使用(支持pjax跳转)
                parent_div_git.insertAdjacentHTML("afterbegin",item_html) // 有报错，但不影响使用(支持pjax跳转)
            }if( document.getElementsByClassName('sticky_layout')[0] && (location.pathname ==='/'|| '/' ==='all')){

            history_calendar_injector_config()
        } </script><script data-pjax  src="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.js"></script><script data-pjax src="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-card-history/baiduhistory/js/main.js"></script><script data-pjax>
    function butterfly_categories_card_injector_config(){
      var parent_div_git = document.getElementById('recent-posts');
      var item_html = '<style>li.categoryBar-list-item{width:24%;}.categoryBar-list{max-height: 190px;overflow:auto;}.categoryBar-list::-webkit-scrollbar{width:0!important}@media screen and (max-width: 650px){.categoryBar-list{max-height: 160px;}}</style><div class="recent-post-item" style="height:auto;width:100%;padding:0px;"><div id="categoryBar"><ul class="categoryBar-list"><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpicnew6.photophoto.cn%2F20120106%2Fhaimianbaobaotupian-10036689_1.jpg&amp;refer=http%3A%2F%2Fpicnew6.photophoto.cn&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648815&amp;t=a3deb15ddd7a38597964c3a05e519bd7);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/Asp-Net/&quot;);" href="javascript:void(0);">Asp.Net</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://npm.elemecdn.com/anzhiyu-blog@1.1.6/img/post/common/site-backgound.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/C-系列/&quot;);" href="javascript:void(0);">C#系列</a><span class="categoryBar-list-count">8</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13012860773%2F1000.jpg&amp;refer=http%3A%2F%2Finews.gtimg.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648865&amp;t=1d2f13b52a7e279e8801545f59eda4e7);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/Hexo重装记录/&quot;);" href="javascript:void(0);">Hexo重装记录</a><span class="categoryBar-list-count">2</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202011%2F07%2F20201107183300_ac0c5.thumb.1000_0.jpeg&amp;refer=http%3A%2F%2Fc-ssl.duitang.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648887&amp;t=3d32c6b12a4cf12e5cec3585b79c1fc3);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/EF/&quot;);" href="javascript:void(0);">EF</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2Fedpic%2F25%2Feb%2F1f%2F25eb1fd40b5a740c2b79e33f700806e5.jpg&amp;refer=http%3A%2F%2Fup.enterdesk.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648908&amp;t=6425ee3bd166b0f5c5ffa6fb18b6937b);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/LOL/&quot;);" href="javascript:void(0);">LOL</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Flmg.jj20.com%2Fup%2Fallimg%2Ftx26%2F36080017392073.jpg&amp;refer=http%3A%2F%2Flmg.jj20.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665650136&amp;t=5cc414d0ee58c9e285218d92f6a95513);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/idea/&quot;);" href="javascript:void(0);">idea</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn10%2F320%2Fw700h420%2F20180907%2F5116-hitesuz6599636.jpg&amp;refer=http%3A%2F%2Fn.sinaimg.cn&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665650004&amp;t=6a304aa9cc7435ec1d148b8f99092bc0);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/世界/&quot;);" href="javascript:void(0);">世界</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxCi6.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/世界见闻录/&quot;);" href="javascript:void(0);">世界见闻录</a><span class="categoryBar-list-count">8</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxFzD.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/前端体系/&quot;);" href="javascript:void(0);">前端体系</a><span class="categoryBar-list-count">19</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxnot.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/副业/&quot;);" href="javascript:void(0);">副业</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxMJf.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/文案/&quot;);" href="javascript:void(0);">文案</a><span class="categoryBar-list-count">6</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxQW8.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/办公日常/&quot;);" href="javascript:void(0);">办公日常</a><span class="categoryBar-list-count">2</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAx3Qg.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/朝花夕拾/&quot;);" href="javascript:void(0);">朝花夕拾</a><span class="categoryBar-list-count">12</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxYes.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/前端/&quot;);" href="javascript:void(0);">前端</a><span class="categoryBar-list-count">20</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(undefined);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/杂七杂八/&quot;);" href="javascript:void(0);">杂七杂八</a><span class="categoryBar-list-count">7</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(undefined);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/简书/&quot;);" href="javascript:void(0);">简书</a><span class="categoryBar-list-count">5</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(undefined);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/游戏/&quot;);" href="javascript:void(0);">游戏</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li></ul></div></div>';
      console.log('已挂载butterfly_categories_card')
      parent_div_git.insertAdjacentHTML("afterbegin",item_html)
      }
    if( document.getElementById('recent-posts') && (location.pathname ==='/'|| '/' ==='all')){
    butterfly_categories_card_injector_config()
    }
  </script><script data-pjax>
  function butterfly_clock_anzhiyu_injector_config(){
    var parent_div_git = document.getElementsByClassName('sticky_layout')[0];
    var item_html = '<div class="card-widget card-clock"><div class="card-glass"><div class="card-background"><div class="card-content"><div id="hexo_electric_clock"><img class="entered loading" id="card-clock-loading" src= "" data-lazy-src="https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu/lib/loading.gif" style="height: 120px; width: 100%;" data-ll-status="loading"/></div></div></div></div></div>';
    console.log('已挂载butterfly_clock_anzhiyu')
    parent_div_git.insertAdjacentHTML("afterbegin",item_html)
    }
  var elist = 'null'.split(',');
  var cpage = location.pathname;
  var epage = '/';
  var qweather_key = '41ea442da35546559913a6a5d54163b2';
  var gaud_map_key = '6b62fbebf584b9a22a85bfccbf90335e';
  var baidu_ak_key = 'undefined';
  var flag = 0;
  var clock_rectangle = '114.35,34.79';
  var clock_default_rectangle_enable = 'true';

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_clock_anzhiyu_injector_config();
  }
  else if (epage === cpage){
    butterfly_clock_anzhiyu_injector_config();
  }
  </script><script src="https://widget.qweather.net/simple/static/js/he-simple-common.js?v=2.0"></script><script data-pjax src="https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu/lib/clock.min.js"></script><script data-pjax>
  function butterfly_footer_beautify_injector_config(){
    var parent_div_git = document.getElementById('footer-wrap');
    var item_html = '<div id="workboard"></div><p id="ghbdages"><a class="github-badge" target="_blank" href="https://hexo.io/" style="margin-inline:5px" data-title="博客框架为Hexo_v5.4.0" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/Frame-Hexo-blue?style=flat&amp;logo=hexo" alt=""/></a><a class="github-badge" target="_blank" href="https://butterfly.js.org/" style="margin-inline:5px" data-title="主题版本Butterfly_v4.2.2" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&amp;logo=bitdefender" alt=""/></a><a class="github-badge" target="_blank" href="https://www.jsdelivr.com/" style="margin-inline:5px" data-title="本站使用JsDelivr为静态资源提供CDN加速" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/CDN-jsDelivr-orange?style=flat&amp;logo=jsDelivr" alt=""/></a><a class="github-badge" target="_blank" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" style="margin-inline:5px" data-title="本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&amp;logo=Claris" alt=""/></a></p>';
    console.log('已挂载butterfly_footer_beautify')
    parent_div_git.insertAdjacentHTML("beforeend",item_html)
    }
  var elist = 'null'.split(',');
  var cpage = location.pathname;
  var epage = 'all';
  var flag = 0;

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_footer_beautify_injector_config();
  }
  else if (epage === cpage){
    butterfly_footer_beautify_injector_config();
  }
  </script><script async src="/js/runtime/runtime.min.js"></script><script data-pjax>
  function butterfly_swiper_injector_config(){
    var parent_div_git = document.getElementById('recent-posts');
    var item_html = '<div class="recent-post-item swiper_container_card" style="height: auto;width: 100%"><div id="random"><div id="random-banner"><canvas id="peoplecanvas"></canvas></div><a id="random-hover" style="width:100%;height:auto;" href="javascript:toRandomPost()" rel="external nofollow noreferrer" one-link-mark="yes"><i class="fa fa-paper-plane" style="margin-left:10px"></i><div style="margin-left:10px">随便逛逛<i class="fa-solid fa-arrow-right" style="margin-left:10px"></i></div></a></div><div class="blog-slider swiper-container-fade swiper-container-horizontal" id="swiper_container"><div class="blog-slider__wrp swiper-wrapper" style="transition-duration: 0ms;"><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/67fcd28d.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://img2.baidu.com/it/u=4087346614,241521689&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=500&amp;h=333" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-19</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/67fcd28d.html&quot;);" href="javascript:void(0);" alt="">学生人到职业人_心态篇</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/67fcd28d.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/8a73f76c.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/04/xLiBTA.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-11-04</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/8a73f76c.html&quot;);" href="javascript:void(0);" alt="">生活の奇思妙想☞2022</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/8a73f76c.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/14e5dae6.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/21/xcAQDH.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-11-12</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/14e5dae6.html&quot;);" href="javascript:void(0);" alt="">少年自负凌云笔</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/14e5dae6.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/9b7092b7.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNJbF0.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-13</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/9b7092b7.html&quot;);" href="javascript:void(0);" alt="">租房有感</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/9b7092b7.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/94bbc7d.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNJLWT.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-25</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/94bbc7d.html&quot;);" href="javascript:void(0);" alt="">谷歌收藏</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/94bbc7d.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/3b350f14.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNJJd1.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-13</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/3b350f14.html&quot;);" href="javascript:void(0);" alt="">阳光不燥、微风正好</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/3b350f14.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div></div><div class="blog-slider__pagination swiper-pagination-clickable swiper-pagination-bullets"></div></div></div>';
    console.log('已挂载butterfly_swiper')
    parent_div_git.insertAdjacentHTML("afterbegin",item_html)
    }
  var elist = 'undefined'.split(',');
  var cpage = location.pathname;
  var epage = '/';
  var flag = 0;

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_swiper_injector_config();
  }
  else if (epage === cpage){
    butterfly_swiper_injector_config();
  }
  </script><script defer src="https://npm.elemecdn.com/anzhiyu-blog@1.1.6/js/swiper.min.js"></script><script defer data-pjax src="https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/swiper_init.js"></script><script data-pjax src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/gsap/3.9.1/gsap.min.js"></script><script defer src="https://npm.elemecdn.com/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/people.min.js"></script><script async src="/anzhiyu/random.js"></script><div class="js-pjax"><script async="async">var arr = document.getElementsByClassName('recent-post-item');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__zoomIn');
    arr[i].setAttribute('data-wow-duration', '1.5s');
    arr[i].setAttribute('data-wow-delay', '200ms');
    arr[i].setAttribute('data-wow-offset', '30');
    arr[i].setAttribute('data-wow-iteration', '1');
  }</script><script async="async">var arr = document.getElementsByClassName('card-widget');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__zoomIn');
    arr[i].setAttribute('data-wow-duration', '');
    arr[i].setAttribute('data-wow-delay', '200ms');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('flink-list-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__flipInY');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('flink-list-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__animated');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('article-sort-item');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__slideInRight');
    arr[i].setAttribute('data-wow-duration', '1.5s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('site-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__flipInY');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('site-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__animated');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script></div><script defer src="https://cdn.cbd.int/hexo-butterfly-wowjs/lib/wow.min.js"></script><script defer src="https://cdn.cbd.int/hexo-butterfly-wowjs/lib/wow_init.js"></script><script async src="/js/ali_font.js"></script><!-- hexo injector body_end end --><script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"tagMode":false,"debug":false,"model":{"jsonPath":"/live2dw/assets/koharu.model.json"},"display":{"position":"left","width":150,"height":300},"mobile":{"show":false},"log":false,"pluginJsPath":"lib/","pluginModelPath":"assets/","pluginRootPath":"live2dw/"});</script></body></html>